Sync with trunk head (part 1 of 2)
authorAmine Khaldi <amine.khaldi@reactos.org>
Mon, 3 May 2010 12:54:59 +0000 (12:54 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Mon, 3 May 2010 12:54:59 +0000 (12:54 +0000)
svn path=/branches/header-work/; revision=47094

630 files changed:
ReactOS-arm.rbuild
base/applications/cmdutils/reg/reg.rbuild
base/applications/downloader/downloader.rbuild
base/applications/fontview/fontview.rbuild
base/applications/kbswitch/kbswitch.rbuild
base/applications/magnify/magnify.rbuild
base/applications/mplay32/mplay32.rbuild
base/applications/mscutils/eventvwr/eventvwr.rbuild
base/applications/network/ping/ping.c
base/applications/notepad/settings.c
base/applications/notepad/text.c
base/applications/paint/lang/it-IT.rc
base/applications/paint/main.c
base/applications/paint/mouse.c
base/applications/rapps/rapps.rbuild
base/applications/rapps/rapps/firefox3.txt
base/applications/rapps/rapps/mirandaim.txt
base/applications/rapps/rapps/openttd.txt
base/applications/rapps/rapps/opera.txt
base/applications/rapps/rapps/scite.txt
base/applications/rapps/rapps/scummvm.txt
base/applications/rapps/rapps/seamonkey.txt
base/applications/rapps/rapps/thunderbird.txt
base/applications/rapps/rapps/utorrent.txt
base/applications/regedit/framewnd.c
base/applications/taskmgr/applpage.c
base/applications/taskmgr/perfdata.c
base/applications/taskmgr/perfdata.h
base/applications/taskmgr/procpage.c
base/applications/taskmgr/taskmgr.c
base/applications/winhlp32/hlpfile.c
base/applications/winver/winver.rbuild
base/services/rpcss/rpcss.rbuild
base/services/telnetd/telnetd.rbuild
base/services/tftpd/tftpd.rbuild
base/setup/usetup/bootsup.c
base/setup/usetup/inffile.c
base/setup/usetup/inffile.h
base/setup/usetup/interface/usetup.c
base/setup/usetup/registry.c
base/setup/usetup/registry.h
base/setup/usetup/usetup.rbuild
base/shell/cmd/console.c
base/shell/cmd/filecomp.c
base/shell/explorer/res/startmenu.ico
base/system/format/format.c
base/system/runonce/runonce.rbuild
base/system/userinit/userinit.c
boot/bootdata/bootcd/bootcd.rbuild
boot/bootdata/hivecls_arm.inf
boot/bootdata/hivecls_i386.inf
boot/bootdata/hivedef_arm.inf
boot/bootdata/hivedef_i386.inf
boot/bootdata/livecd/livecd.rbuild
boot/bootdata/packages/reactos.dff
boot/bootdata/txtsetup.sif
boot/freeldr/freeldr/arch/amd64/arch.S
boot/freeldr/freeldr/arch/amd64/boot.S
boot/freeldr/freeldr/arch/amd64/drvmap.S
boot/freeldr/freeldr/arch/amd64/i386cpu.S
boot/freeldr/freeldr/arch/amd64/i386pnp.S
boot/freeldr/freeldr/arch/amd64/i386trap.S
boot/freeldr/freeldr/arch/amd64/int386.S
boot/freeldr/freeldr/arch/amd64/loader.c
boot/freeldr/freeldr/arch/amd64/mb.S
boot/freeldr/freeldr/arch/i386/hardware.c
boot/freeldr/freeldr/arch/i386/machpc.c
boot/freeldr/freeldr/arch/i386/machxbox.c
boot/freeldr/freeldr/arch/i386/miscboot.c
boot/freeldr/freeldr/arch/i386/xboxhw.c
boot/freeldr/freeldr/arch/powerpc/mach.c
boot/freeldr/freeldr/disk/disk.c
boot/freeldr/freeldr/disk/partition.c
boot/freeldr/freeldr/freeldr_arch.rbuild
boot/freeldr/freeldr/freeldr_base.rbuild
boot/freeldr/freeldr/include/arch/amd64/amd64.h
boot/freeldr/freeldr/include/disk.h
boot/freeldr/freeldr/include/machine.h
boot/freeldr/freeldr/linuxboot.c
boot/freeldr/freeldr/machine.c
boot/freeldr/freeldr/reactos/arcname.c
boot/freeldr/freeldr/reactos/reactos.c
boot/freeldr/freeldr/windows/amd64/wlmemory.c
dll/cpl/desk/appearance.c
dll/cpl/desk/background.c
dll/cpl/desk/effappdlg.c
dll/cpl/sysdm/lang/uk-UA.rc
dll/directx/bdaplgin/pincontrol.cpp
dll/directx/ksproxy/allocator.cpp
dll/directx/ksproxy/enumpins.cpp
dll/directx/ksproxy/input_pin.cpp
dll/directx/ksproxy/mediasample.cpp
dll/directx/ksproxy/output_pin.cpp
dll/directx/ksproxy/precomp.h
dll/directx/ksproxy/proxy.cpp
dll/directx/msdvbnp/enumpins.cpp
dll/directx/msdvbnp/msdvbnp.cpp
dll/directx/msdvbnp/precomp.h
dll/directx/qedit/samplegrabber.c
dll/directx/quartz/avidec.c
dll/directx/quartz/avisplit.c
dll/ntdll/ldr/utils.c
dll/win32/activeds/activeds.spec
dll/win32/activeds/activeds_main.c
dll/win32/actxprxy/actxprxy.rbuild
dll/win32/atl/atl_ax.c
dll/win32/avifil32/rsrc.rc
dll/win32/cabinet/fdi.c
dll/win32/comdlg32/filedlg.c
dll/win32/comdlg32/fontdlg.c
dll/win32/comdlg32/printdlg.c
dll/win32/crypt32/base64.c
dll/win32/crypt32/decode.c
dll/win32/devmgr/lang/cs-CZ.rc
dll/win32/gdi32/include/gdi32p.h
dll/win32/gdi32/objects/dc.c
dll/win32/gdi32/objects/region.c
dll/win32/gdiplus/brush.c
dll/win32/gdiplus/font.c
dll/win32/gdiplus/gdiplus.spec
dll/win32/gdiplus/gdiplus_private.h
dll/win32/gdiplus/graphics.c
dll/win32/gdiplus/image.c
dll/win32/hhctrl.ocx/hhctrl.c
dll/win32/inetcomm/mimeintl.c
dll/win32/inetcomm/mimeole.c
dll/win32/inseng/inseng_main.c
dll/win32/jscript/jscript.h
dll/win32/jscript/regexp.c
dll/win32/jscript/string.c
dll/win32/kernel32/file/dir.c
dll/win32/kernel32/kernel32.pspec
dll/win32/kernel32/misc/stubs.c
dll/win32/localspl/provider.c
dll/win32/lpk/dllmain.c
dll/win32/mciavi32/mciavi.c
dll/win32/mcicda/mcicda.c
dll/win32/mciqtz32/mciqtz.c
dll/win32/mciqtz32/mciqtz_private.h
dll/win32/mciseq/mcimidi.c
dll/win32/mciwave/mciwave.c
dll/win32/msacm32/msacm32.rbuild
dll/win32/mscoree/mscoree.rbuild
dll/win32/mscoree/mscoree.spec
dll/win32/mscoree/mscoree_main.c
dll/win32/mscoree/mscoree_private.h
dll/win32/msctf/displayattributemgr.c [new file with mode: 0644]
dll/win32/msctf/inputprocessor.c
dll/win32/msctf/msctf.c
dll/win32/msctf/msctf.rbuild
dll/win32/msctf/msctf_internal.h
dll/win32/msctf/regsvr.c
dll/win32/msgsm32.acm/msgsm32.c
dll/win32/mshtml/dispex.c
dll/win32/mshtml/editor.c
dll/win32/mshtml/htmlelem.c
dll/win32/mshtml/htmlwindow.c
dll/win32/mshtml/install.c
dll/win32/mshtml/mshtml_private.h
dll/win32/mshtml/navigate.c
dll/win32/mshtml/nsembed.c
dll/win32/mshtml/nsevents.c
dll/win32/mshtml/nsio.c
dll/win32/mshtml/olecmd.c
dll/win32/mshtml/view.c
dll/win32/msimtf/activeimmapp.c
dll/win32/msvfw32/mciwnd.c
dll/win32/msvfw32/msvfw32_ros.diff [deleted file]
dll/win32/msvfw32/msvideo16.c [deleted file]
dll/win32/msvfw32/vfw16.h [deleted file]
dll/win32/msvidc32/msvideo1.c
dll/win32/msxml3/dispex.c
dll/win32/msxml3/element.c
dll/win32/msxml3/main.c
dll/win32/msxml3/node.c
dll/win32/netcfgx/lang/cs-CZ.rc
dll/win32/netcfgx/netcfgx.c
dll/win32/netcfgx/tcpipconf_notify.c
dll/win32/netid/lang/cs-CZ.rc
dll/win32/netid/lang/it-IT.rc
dll/win32/netshell/lang/bg-BG.rc
dll/win32/netshell/lang/cs-CZ.rc
dll/win32/netshell/lang/da-DK.rc
dll/win32/netshell/lang/de-DE.rc
dll/win32/netshell/lang/el-GR.rc
dll/win32/netshell/lang/en-US.rc
dll/win32/netshell/lang/es-ES.rc
dll/win32/netshell/lang/fr-FR.rc
dll/win32/netshell/lang/hu-HU.rc
dll/win32/netshell/lang/id-ID.rc
dll/win32/netshell/lang/it-IT.rc
dll/win32/netshell/lang/ja-JP.rc
dll/win32/netshell/lang/nl-NL.rc
dll/win32/netshell/lang/no-NO.rc
dll/win32/netshell/lang/pl-PL.rc
dll/win32/netshell/lang/ro-RO.rc
dll/win32/netshell/lang/ru-RU.rc
dll/win32/netshell/lang/sv-SE.rc
dll/win32/netshell/lang/uk-UA.rc
dll/win32/netshell/lang/zh-CN.rc
dll/win32/netshell/lanstatusui.c
dll/win32/ntmarta/ntmarta.c
dll/win32/ole32/compobj.c
dll/win32/ole32/ftmarshal.c
dll/win32/ole32/ifs.c
dll/win32/ole32/moniker.c
dll/win32/ole32/ole32.rbuild
dll/win32/ole32/rpc.c
dll/win32/ole32/storage32.c
dll/win32/ole32/storage32.h
dll/win32/oleaut32/olepicture.c
dll/win32/oleaut32/regsvr.c
dll/win32/oleaut32/typelib.c
dll/win32/oleaut32/typelib2.c
dll/win32/oleaut32/vartype.c
dll/win32/rsaenh/rsaenh.c
dll/win32/rsaenh/sha2.c
dll/win32/schannel/lsamode.c
dll/win32/setupapi/interface.c
dll/win32/setupapi/lang/cs-CZ.rc
dll/win32/shell32/dialogs.c
dll/win32/shell32/folder_options.c
dll/win32/shell32/folders.c
dll/win32/shell32/fprop.c
dll/win32/shell32/lang/bg-BG.rc
dll/win32/shell32/lang/ca-ES.rc
dll/win32/shell32/lang/cs-CZ.rc
dll/win32/shell32/lang/da-DK.rc
dll/win32/shell32/lang/de-DE.rc
dll/win32/shell32/lang/el-GR.rc
dll/win32/shell32/lang/en-GB.rc
dll/win32/shell32/lang/en-US.rc
dll/win32/shell32/lang/es-ES.rc
dll/win32/shell32/lang/fi-FI.rc
dll/win32/shell32/lang/fr-FR.rc
dll/win32/shell32/lang/hu-HU.rc
dll/win32/shell32/lang/it-IT.rc
dll/win32/shell32/lang/ja-JP.rc
dll/win32/shell32/lang/ko-KR.rc
dll/win32/shell32/lang/nl-NL.rc
dll/win32/shell32/lang/no-NO.rc
dll/win32/shell32/lang/pl-PL.rc
dll/win32/shell32/lang/pt-BR.rc
dll/win32/shell32/lang/pt-PT.rc
dll/win32/shell32/lang/ro-RO.rc
dll/win32/shell32/lang/ru-RU.rc
dll/win32/shell32/lang/sk-SK.rc
dll/win32/shell32/lang/sl-SI.rc
dll/win32/shell32/lang/sv-SE.rc
dll/win32/shell32/lang/tr-TR.rc
dll/win32/shell32/lang/uk-UA.rc
dll/win32/shell32/lang/zh-CN.rc
dll/win32/shell32/lang/zh-TW.rc
dll/win32/shell32/she_ocmenu.c
dll/win32/shell32/shfldr_cpanel.c
dll/win32/shell32/shfldr_fonts.c
dll/win32/shell32/shlfileop.c
dll/win32/shell32/shresdef.h
dll/win32/shell32/shv_def_cmenu.c
dll/win32/shlwapi/ordinal.c
dll/win32/shlwapi/shlwapi.spec
dll/win32/shlwapi/url.c
dll/win32/sti/regsvr.c
dll/win32/sti/sti.c [new file with mode: 0644]
dll/win32/sti/sti.rbuild
dll/win32/sti/sti.spec
dll/win32/sti/sti_main.c
dll/win32/sti/sti_private.h [new file with mode: 0644]
dll/win32/sti/sti_wia.idl [new file with mode: 0644]
dll/win32/syssetup/lang/it-IT.rc
dll/win32/syssetup/wizard.c
dll/win32/urlmon/bindprot.c
dll/win32/urlmon/regsvr.c
dll/win32/urlmon/urlmon_main.c
dll/win32/urlmon/urlmon_main.h
dll/win32/urlmon/urlmon_urlmon.idl
dll/win32/urlmon/usrmarshal.c
dll/win32/user32/controls/button.c
dll/win32/user32/misc/stubs.c
dll/win32/user32/windows/menu.c
dll/win32/userenv/lang/cs-CZ.rc
dll/win32/userenv/setup.c
dll/win32/usp10/bidi.c [new file with mode: 0644]
dll/win32/usp10/usp10.c
dll/win32/usp10/usp10.rbuild
dll/win32/usp10/usp10.spec
dll/win32/usp10/usp10_internal.h [new file with mode: 0644]
dll/win32/version/resource.c
dll/win32/windowscodecs/bmpdecode.c
dll/win32/windowscodecs/clsfactory.c
dll/win32/windowscodecs/converter.c
dll/win32/windowscodecs/gifformat.c
dll/win32/windowscodecs/icoformat.c
dll/win32/windowscodecs/jpegformat.c
dll/win32/windowscodecs/palette.c
dll/win32/windowscodecs/pngformat.c
dll/win32/windowscodecs/regsvr.c
dll/win32/windowscodecs/stream.c
dll/win32/windowscodecs/tiffformat.c [new file with mode: 0644]
dll/win32/windowscodecs/wincodecs_private.h
dll/win32/windowscodecs/windowscodecs.rbuild
dll/win32/wininet/internet.c
dll/win32/wininet/urlcache.c
dll/win32/wintrust/asn.c
dll/win32/ws2_32/misc/ns.c
drivers/bus/acpi/acpi.rbuild
drivers/bus/directory.rbuild
drivers/bus/isapnp/fdo.c [new file with mode: 0644]
drivers/bus/isapnp/hardware.c [new file with mode: 0644]
drivers/bus/isapnp/isapnp.c
drivers/bus/isapnp/isapnp.h
drivers/bus/isapnp/isapnp.rbuild
drivers/bus/isapnp/isapnphw.h [new file with mode: 0644]
drivers/bus/isapnp/pdo.c [new file with mode: 0644]
drivers/bus/pci/fdo.c
drivers/bus/pci/pdo.c
drivers/bus/pcmcia/fdo.c [new file with mode: 0644]
drivers/bus/pcmcia/pcmcia.c [new file with mode: 0644]
drivers/bus/pcmcia/pcmcia.h [new file with mode: 0644]
drivers/bus/pcmcia/pcmcia.rbuild [new file with mode: 0644]
drivers/bus/pcmcia/pcmcia.rc [new file with mode: 0644]
drivers/bus/pcmcia/pdo.c [new file with mode: 0644]
drivers/ksfilter/ks/allocators.c
drivers/ksfilter/ks/api.c
drivers/ksfilter/ks/bag.c
drivers/ksfilter/ks/clocks.c
drivers/ksfilter/ks/connectivity.c
drivers/ksfilter/ks/device.c
drivers/ksfilter/ks/deviceinterface.c
drivers/ksfilter/ks/driver.c
drivers/ksfilter/ks/filter.c
drivers/ksfilter/ks/filterfactory.c
drivers/ksfilter/ks/irp.c
drivers/ksfilter/ks/ksfunc.h
drivers/ksfilter/ks/ksiface.h
drivers/ksfilter/ks/kstypes.h
drivers/ksfilter/ks/methods.c
drivers/ksfilter/ks/misc.c
drivers/ksfilter/ks/pin.c
drivers/ksfilter/ks/priv.h
drivers/ksfilter/ks/property.c
drivers/ksfilter/ks/topology.c
drivers/multimedia/bdasup/precomp.h
drivers/network/afd/afd/lock.c
drivers/network/ndis/ndis.def [deleted file]
drivers/network/ndis/ndis.rbuild
drivers/network/ndis/ndis.spec [new file with mode: 0644]
drivers/network/ndis/ndis/miniport.c
drivers/network/tdi/misc/tdi.def [deleted file]
drivers/network/tdi/misc/tdi.spec [new file with mode: 0644]
drivers/network/tdi/tdi.rbuild
drivers/storage/class/cdrom/cdrom.c
drivers/storage/class/ramdisk/ramdisk.c
drivers/storage/ide/uniata/id_ata.cpp
drivers/usb/usbehci/common.c
drivers/usb/usbehci/fdo.c
drivers/usb/usbehci/irp.c
drivers/usb/usbehci/pdo.c
drivers/usb/usbehci/urbreq.c
drivers/usb/usbehci/usbehci.c
drivers/usb/usbehci/usbehci.h
drivers/usb/usbehci/usbiffn.c
drivers/usb/usbehci/usbiffn.h
drivers/video/displays/vga/objects/pointer.c
hal/halx86/directory.rbuild
hal/halx86/generic/acpi/halpnpdd.c
hal/halx86/generic/halinit.c
hal/halx86/hal_generic.rbuild
hal/halx86/hal_mini.rbuild [new file with mode: 0644]
hal/halx86/halamd64.rbuild
include/ddk/hubbusif.h
include/ddk/ntddk.h
include/ddk/usbbusif.h
include/dxsdk/bdamedia.h
include/host/typedefs.h
include/host/wcsfuncs.h
include/ndk/amd64/ketypes.h
include/psdk/gdiplusflat.h
include/psdk/ks.h
include/psdk/ksmedia.h
include/psdk/ntdef.h
include/psdk/ntsecpkg.h
include/psdk/objbase.h
include/psdk/psdk.rbuild
include/psdk/shdeprecated.idl [new file with mode: 0644]
include/psdk/shlwapi.h
include/psdk/sti.h
include/psdk/strsafe.h [new file with mode: 0644]
include/psdk/wia.h [new file with mode: 0644]
include/psdk/wia_lh.idl [new file with mode: 0644]
include/psdk/wia_xp.idl [new file with mode: 0644]
include/psdk/winbase.h
include/psdk/wingdi.h
include/psdk/winnt.h
include/psdk/winuser.h
include/reactos/arm/armddk.h
include/reactos/asm.h
include/reactos/win32k/ntgdityp.h
include/xdk/exfuncs.h
lib/cmlib/cminit.c
lib/cmlib/cmlib.h
lib/cmlib/cmlib.rbuild
lib/cmlib/hivecell.c
lib/cmlib/hivewrt.c
lib/drivers/ip/transport/tcp/tcp.c
lib/drivers/oskittcp/oskittcp/osenv.c
lib/drivers/sound/mmixer/wave.c
lib/host/wcsfuncs/wcsfuncs.c
lib/lib.rbuild
lib/newinflib/README.txt [new file with mode: 0644]
lib/newinflib/builddep.h [new file with mode: 0644]
lib/newinflib/infcommon.h [new file with mode: 0644]
lib/newinflib/infcore.c [new file with mode: 0644]
lib/newinflib/infget.c [new file with mode: 0644]
lib/newinflib/infhost.h [new file with mode: 0644]
lib/newinflib/infhostgen.c [new file with mode: 0644]
lib/newinflib/infhostget.c [new file with mode: 0644]
lib/newinflib/infhostput.c [new file with mode: 0644]
lib/newinflib/infhostrtl.c [new file with mode: 0644]
lib/newinflib/inflib.h [new file with mode: 0644]
lib/newinflib/inflib.mak [new file with mode: 0644]
lib/newinflib/inflib.rbuild [new file with mode: 0644]
lib/newinflib/infpriv.h [new file with mode: 0644]
lib/newinflib/infput.c [new file with mode: 0644]
lib/newinflib/infros.h [new file with mode: 0644]
lib/newinflib/infrosgen.c [new file with mode: 0644]
lib/newinflib/infrosget.c [new file with mode: 0644]
lib/newinflib/infrosput.c [new file with mode: 0644]
lib/rtl/message.c
lib/rtl/sprintf.c
lib/rtl/swprintf.c
media/doc/README.WINE
media/drivers/etc/etc.rbuild
media/drivers/etc/hosts [new file with mode: 0644]
media/inf/cpu.inf
media/inf/display.inf
media/inf/fdc.inf
media/inf/hdc.inf
media/inf/machine.inf
ntoskrnl/config/cmapi.c
ntoskrnl/config/cmboot.c
ntoskrnl/config/cmdata.c
ntoskrnl/config/cmhvlist.c
ntoskrnl/config/cminit.c
ntoskrnl/config/cmkcbncb.c
ntoskrnl/config/cmparse.c
ntoskrnl/config/cmsysini.c
ntoskrnl/include/internal/cm.h
ntoskrnl/include/internal/i386/intrin_i.h
ntoskrnl/include/internal/io.h
ntoskrnl/io/iomgr/device.c
ntoskrnl/io/iomgr/deviface.c
ntoskrnl/io/iomgr/driver.c
ntoskrnl/io/iomgr/drvrlist.c [deleted file]
ntoskrnl/io/iomgr/iomgr.c
ntoskrnl/io/pnpmgr/pnpinit.c [new file with mode: 0644]
ntoskrnl/io/pnpmgr/pnpmgr.c
ntoskrnl/io/pnpmgr/pnpnotify.c
ntoskrnl/io/pnpmgr/pnpreport.c
ntoskrnl/io/pnpmgr/pnpres.c [new file with mode: 0644]
ntoskrnl/io/pnpmgr/pnproot.c
ntoskrnl/io/pnpmgr/pnputil.c [new file with mode: 0644]
ntoskrnl/kdbg/kdb_cli.c
ntoskrnl/ke/i386/exp.c
ntoskrnl/ke/i386/traphdlr.c
ntoskrnl/mm/ARM3/drvmgmt.c
ntoskrnl/mm/ARM3/largepag.c [new file with mode: 0644]
ntoskrnl/mm/ARM3/mdlsup.c
ntoskrnl/mm/ARM3/miarm.h
ntoskrnl/mm/ARM3/mminit.c
ntoskrnl/mm/ARM3/pfnlist.c
ntoskrnl/mm/ARM3/pool.c
ntoskrnl/mm/freelist.c
ntoskrnl/mm/mminit.c
ntoskrnl/mm/pagefile.c
ntoskrnl/mm/section.c
ntoskrnl/mm/sysldr.c
ntoskrnl/ntoskrnl-generic.rbuild
ntoskrnl/ntoskrnl.pspec
ntoskrnl/rtl/libsupp.c
ntoskrnl/se/semgr.c
rosbuild.bat
subsystems/ntvdm/ntvdm.c
subsystems/win32/csrss/win32csr/dllmain.c
subsystems/win32/csrss/win32csr/harderror.c [new file with mode: 0644]
subsystems/win32/csrss/win32csr/w32csr.h
subsystems/win32/csrss/win32csr/win32csr.rbuild
subsystems/win32/win32k/dib/dib.c
subsystems/win32/win32k/dib/dib16bpp.c
subsystems/win32/win32k/dib/dib1bpp.c
subsystems/win32/win32k/dib/dib24bpp.c
subsystems/win32/win32k/dib/dib24bppc.c
subsystems/win32/win32k/dib/dib32bpp.c
subsystems/win32/win32k/dib/dib32bppc.c
subsystems/win32/win32k/dib/dib4bpp.c
subsystems/win32/win32k/dib/dib8bpp.c
subsystems/win32/win32k/dib/floodfill.c
subsystems/win32/win32k/dib/stretchblt.c
subsystems/win32/win32k/eng/alphablend.c
subsystems/win32/win32k/eng/bitblt.c
subsystems/win32/win32k/eng/clip.c
subsystems/win32/win32k/eng/copybits.c
subsystems/win32/win32k/eng/debug.c
subsystems/win32/win32k/eng/device.c
subsystems/win32/win32k/eng/driverobj.c
subsystems/win32/win32k/eng/engbrush.c
subsystems/win32/win32k/eng/engevent.c
subsystems/win32/win32k/eng/engmisc.c
subsystems/win32/win32k/eng/engwindow.c
subsystems/win32/win32k/eng/error.c
subsystems/win32/win32k/eng/float.c
subsystems/win32/win32k/eng/gradient.c
subsystems/win32/win32k/eng/lineto.c
subsystems/win32/win32k/eng/mapping.c
subsystems/win32/win32k/eng/mem.c
subsystems/win32/win32k/eng/mouse.c
subsystems/win32/win32k/eng/paint.c
subsystems/win32/win32k/eng/perfcnt.c
subsystems/win32/win32k/eng/semaphor.c
subsystems/win32/win32k/eng/sort.c
subsystems/win32/win32k/eng/stretchblt.c
subsystems/win32/win32k/eng/string.c
subsystems/win32/win32k/eng/surface.c
subsystems/win32/win32k/eng/transblt.c
subsystems/win32/win32k/eng/xlate.c
subsystems/win32/win32k/include/coord.h
subsystems/win32/win32k/include/dc.h
subsystems/win32/win32k/include/gdiobj.h
subsystems/win32/win32k/include/msgqueue.h
subsystems/win32/win32k/include/pdevobj.h
subsystems/win32/win32k/include/surface.h
subsystems/win32/win32k/include/win32kp.h [moved from subsystems/win32/win32k/include/win32k.h with 100% similarity]
subsystems/win32/win32k/ldr/loader.c
subsystems/win32/win32k/main/dllmain.c
subsystems/win32/win32k/misc/copy.c
subsystems/win32/win32k/misc/driver.c
subsystems/win32/win32k/misc/err.c
subsystems/win32/win32k/misc/file.c
subsystems/win32/win32k/misc/math.c
subsystems/win32/win32k/misc/registry.c
subsystems/win32/win32k/misc/rtlstr.c
subsystems/win32/win32k/misc/usrheap.c
subsystems/win32/win32k/ntddraw/d3d.c
subsystems/win32/win32k/ntddraw/dd.c
subsystems/win32/win32k/ntddraw/ddraw.c
subsystems/win32/win32k/ntddraw/ddsurf.c
subsystems/win32/win32k/ntddraw/dvp.c
subsystems/win32/win32k/ntddraw/dxeng.c
subsystems/win32/win32k/ntddraw/eng.c
subsystems/win32/win32k/ntddraw/mocomp.c
subsystems/win32/win32k/ntuser/accelerator.c
subsystems/win32/win32k/ntuser/callback.c
subsystems/win32/win32k/ntuser/callproc.c
subsystems/win32/win32k/ntuser/caret.c
subsystems/win32/win32k/ntuser/class.c
subsystems/win32/win32k/ntuser/clipboard.c
subsystems/win32/win32k/ntuser/csr.c
subsystems/win32/win32k/ntuser/cursoricon.c
subsystems/win32/win32k/ntuser/defwnd.c
subsystems/win32/win32k/ntuser/desktop.c
subsystems/win32/win32k/ntuser/display.c
subsystems/win32/win32k/ntuser/event.c
subsystems/win32/win32k/ntuser/focus.c
subsystems/win32/win32k/ntuser/guicheck.c
subsystems/win32/win32k/ntuser/hook.c
subsystems/win32/win32k/ntuser/hotkey.c
subsystems/win32/win32k/ntuser/input.c
subsystems/win32/win32k/ntuser/kbdlayout.c
subsystems/win32/win32k/ntuser/keyboard.c
subsystems/win32/win32k/ntuser/menu.c
subsystems/win32/win32k/ntuser/message.c
subsystems/win32/win32k/ntuser/metric.c
subsystems/win32/win32k/ntuser/misc.c
subsystems/win32/win32k/ntuser/monitor.c
subsystems/win32/win32k/ntuser/msgqueue.c
subsystems/win32/win32k/ntuser/ntstubs.c
subsystems/win32/win32k/ntuser/ntuser.c
subsystems/win32/win32k/ntuser/object.c
subsystems/win32/win32k/ntuser/painting.c
subsystems/win32/win32k/ntuser/prop.c
subsystems/win32/win32k/ntuser/scrollbar.c
subsystems/win32/win32k/ntuser/session.c
subsystems/win32/win32k/ntuser/simplecall.c
subsystems/win32/win32k/ntuser/sysparams.c
subsystems/win32/win32k/ntuser/timer.c
subsystems/win32/win32k/ntuser/useratom.c
subsystems/win32/win32k/ntuser/vis.c
subsystems/win32/win32k/ntuser/windc.c
subsystems/win32/win32k/ntuser/window.c
subsystems/win32/win32k/ntuser/winpos.c
subsystems/win32/win32k/ntuser/winsta.c
subsystems/win32/win32k/objects/arc.c
subsystems/win32/win32k/objects/bezier.c
subsystems/win32/win32k/objects/bitblt.c
subsystems/win32/win32k/objects/bitmaps.c
subsystems/win32/win32k/objects/brush.c
subsystems/win32/win32k/objects/cliprgn.c
subsystems/win32/win32k/objects/coord.c
subsystems/win32/win32k/objects/dcattr.c
subsystems/win32/win32k/objects/dclife.c
subsystems/win32/win32k/objects/dcobjs.c
subsystems/win32/win32k/objects/dcstate.c
subsystems/win32/win32k/objects/dcutil.c
subsystems/win32/win32k/objects/device.c
subsystems/win32/win32k/objects/dibobj.c
subsystems/win32/win32k/objects/drawing.c
subsystems/win32/win32k/objects/fillshap.c
subsystems/win32/win32k/objects/font.c
subsystems/win32/win32k/objects/freetype.c
subsystems/win32/win32k/objects/gdibatch.c
subsystems/win32/win32k/objects/gdidbg.c
subsystems/win32/win32k/objects/gdiobj.c
subsystems/win32/win32k/objects/icm.c
subsystems/win32/win32k/objects/line.c
subsystems/win32/win32k/objects/metafile.c
subsystems/win32/win32k/objects/palette.c
subsystems/win32/win32k/objects/path.c
subsystems/win32/win32k/objects/pen.c
subsystems/win32/win32k/objects/polyfill.c
subsystems/win32/win32k/objects/print.c
subsystems/win32/win32k/objects/rect.c
subsystems/win32/win32k/objects/region.c
subsystems/win32/win32k/objects/stockobj.c
subsystems/win32/win32k/objects/text.c
subsystems/win32/win32k/objects/wingl.c
subsystems/win32/win32k/objects/xformobj.c
subsystems/win32/win32k/pch.h
subsystems/win32/win32k/stubs/stubs.c
subsystems/win32/win32k/stubs/umpdstubs.c
subsystems/win32/win32k/win32k.h [moved from subsystems/win32/win32k/w32k.h with 100% similarity]

index 777a1aa..6d7abe7 100644 (file)
@@ -28,6 +28,7 @@
                <if property="OPTIMIZE" value="1">
                        <compilerflag>-ftracer</compilerflag>
                </if>
+               <compilerflag>-fms-extensions</compilerflag>
         <compilerflag>-Wno-attributes</compilerflag>
         <compilerflag>-U_UNICODE</compilerflag>
         <compilerflag>-UUNICODE</compilerflag>
index ce9a744..ac33ef4 100644 (file)
@@ -1,3 +1,5 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
 <module name="reg" type="win32cui" installbase="system32" installname="reg.exe" unicode="true">
        <include base="reg">.</include>
        <redefine name="_WIN32_WINNT">0x600</redefine>
index 9ea43dc..b45df06 100644 (file)
@@ -1,25 +1,26 @@
 <?xml version="1.0"?>
-<group xmlns:xi="http://www.w3.org/2001/XInclude">
-       <installfile installbase="system32">downloader.xml</installfile>
-       <module name="downloader" type="win32gui" installbase="system32" installname="downloader.exe" unicode="yes">
-               <include base="downloader">.</include>
-               <include base="expat">.</include>
+<!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">
+<group>
+<installfile installbase="system32">downloader.xml</installfile>
+<module name="downloader" type="win32gui" installbase="system32" installname="downloader.exe" unicode="yes">
+       <include base="downloader">.</include>
+       <include base="expat">.</include>
 
-               <library>advapi32</library>
-               <library>ntdll</library>
-               <library>user32</library>
-               <library>gdi32</library>
-               <library>shell32</library>
-               <library>comctl32</library>
-               <library>msimg32</library>
-               <library>shlwapi</library>
-               <library>urlmon</library>
-               <library>uuid</library>
-               <library>expat</library>
+       <library>advapi32</library>
+       <library>ntdll</library>
+       <library>user32</library>
+       <library>gdi32</library>
+       <library>shell32</library>
+       <library>comctl32</library>
+       <library>msimg32</library>
+       <library>shlwapi</library>
+       <library>urlmon</library>
+       <library>uuid</library>
+       <library>expat</library>
 
-               <file>main.c</file>
-               <file>xml.c</file>
-               <file>download.c</file>
-               <file>downloader.rc</file>
-       </module>
+       <file>main.c</file>
+       <file>xml.c</file>
+       <file>download.c</file>
+       <file>downloader.rc</file>
+</module>
 </group>
index 8ceda78..f5cad36 100644 (file)
@@ -1,3 +1,5 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="fontview" type="win32gui" installbase="system32" installname="fontview.exe">
        <include base="fontview">.</include>
        <library>gdi32</library>
index 2eed0b2..11ea960 100644 (file)
@@ -1,4 +1,5 @@
 <?xml version="1.0"?>
+<!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">
 <group xmlns:xi="http://www.w3.org/2001/XInclude">
 <module name="kbswitch" type="win32gui" installbase="system32" installname="kbswitch.exe" unicode="yes">
        <include base="kbswitch">.</include>
index 995437d..8c06ce8 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<!DOCTYPE project SYSTEM "../../../tools/rbuild/project.dtd">
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="magnify" type="win32gui" installbase="system32" installname="magnify.exe">
        <include base="magnify">.</include>
        <library>user32</library>
index c472e6f..77003d9 100644 (file)
@@ -1,3 +1,5 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="mplay32" type="win32gui" installbase="system32" installname="mplay32.exe" unicode="yes">
        <include base="mplay32">.</include>
        <library>advapi32</library>
index 367c19e..cb23e1f 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<rbuild xmlns:xi="http://www.w3.org/2001/XInclude">
+<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
 <module name="eventvwr" type="win32gui" installbase="system32" installname="eventvwr.exe" unicode="yes">
        <include base="eventvwr">.</include>
        <library>user32</library>
@@ -8,4 +8,3 @@
        <file>eventvwr.c</file>
        <file>eventvwr.rc</file>
 </module>
-</rbuild>
index b9635e2..b2d48ca 100644 (file)
@@ -630,8 +630,9 @@ int main(int argc, char* argv[])
         while ((NeverStop) || (Count < PingCount))
         {
             Ping();
-            Sleep(Timeout);
             Count++;
+            if((NeverStop) || (Count < PingCount))
+                Sleep(Timeout);
         };
 
         Cleanup();
index 862e4fb..9a68c8b 100644 (file)
@@ -147,16 +147,16 @@ void LoadSettings(void)
                if (dwPointSize != 0)
                        Globals.lfFont.lfHeight = HeightFromPointSize(dwPointSize);
 
-               hFont = CreateFontIndirect(&Globals.lfFont);
-               if (hFont)
-               {
-                       if (Globals.hFont)
-                               DeleteObject(Globals.hFont);
-                       Globals.hFont = hFont;
-               }
-
                RegCloseKey(hKey);
        }
+
+       hFont = CreateFontIndirect(&Globals.lfFont);
+       if (hFont)
+       {
+               if (Globals.hFont)
+                       DeleteObject(Globals.hFont);
+               Globals.hFont = hFont;
+       }
 }
 
 static BOOL SaveDword(HKEY hKey, LPCTSTR pszValueNameT, DWORD dwValue)
index 6ca1907..ed1015d 100644 (file)
@@ -51,7 +51,7 @@ BOOL ReadText(HANDLE hFile, LPWSTR *ppszText, DWORD *pdwTextLen, int *piEncoding
 {
        DWORD dwSize;
        LPBYTE pBytes = NULL;
-       LPCWSTR pszText;
+       LPWSTR pszText;
        LPWSTR pszAllocText = NULL;
        DWORD dwPos, i;
        DWORD dwCharCount;
@@ -110,7 +110,7 @@ BOOL ReadText(HANDLE hFile, LPWSTR *ppszText, DWORD *pdwTextLen, int *piEncoding
                /* fall through */
 
        case ENCODING_UNICODE:
-               pszText = (LPCWSTR) &pBytes[dwPos];
+               pszText = (LPWSTR) &pBytes[dwPos];
                dwCharCount = (dwSize - dwPos) / sizeof(WCHAR);
                break;
 
@@ -174,6 +174,10 @@ BOOL ReadText(HANDLE hFile, LPWSTR *ppszText, DWORD *pdwTextLen, int *piEncoding
                        else
                                adwEolnCount[EOLN_LF]++;
                        break;
+
+               case '\0':
+                       pszText[i] = ' ';
+                       break;
                }
        }
 
index d7b7c9e..2c38106 100644 (file)
@@ -60,8 +60,8 @@ BEGIN
                 MENUITEM "800%", IDM_VIEWZOOM800
             END
             MENUITEM SEPARATOR
-            MENUITEM "Show grid", IDM_VIEWSHOWGRID
-            MENUITEM "Show miniature", IDM_VIEWSHOWMINIATURE
+            MENUITEM "Mostra griglia", IDM_VIEWSHOWGRID
+            MENUITEM "Mostra miniature", IDM_VIEWSHOWMINIATURE
         END
         MENUITEM "Visualizza a schermo intero\tCtrl+F", IDM_VIEWFULLSCREEN
     END
@@ -201,5 +201,5 @@ BEGIN
     IDS_OPENFILTER, "Bitmap files (*.bmp;*.dib)\1*.bmp;*.dib\1All files (*.*)\1*.*\1"
     IDS_SAVEFILTER, "24 bit bitmap (*.bmp;*.dib)\1*.bmp;*.dib\1"
     IDS_FILESIZE, "%d bytes"
-    IDS_PRINTRES, "%d x %d pixels per meter"
+    IDS_PRINTRES, "%d x %d pixels per metro"
 END
index 98565f4..9042205 100644 (file)
@@ -143,6 +143,7 @@ _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument
     HBITMAP tempBm;
     int i;
     TCHAR tooltips[16][30];
+    HDC hDC;
     
     TCHAR *c;
     TCHAR sfnFilename[1000];
@@ -152,7 +153,7 @@ _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument
     TCHAR ofnFiletitle[256];
     TCHAR ofnFilter[1000];
     TCHAR miniaturetitle[100];
-    int custColors[16] = { 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
+    static int custColors[16] = { 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
         0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff
     };
 
@@ -371,8 +372,10 @@ _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument
         CreateWindowEx(0, _T("Scrollbox"), _T(""), WS_CHILD | WS_VISIBLE, 3, 3, imgXRes, imgYRes, hScrlClient,
                        NULL, hThisInstance, NULL);
 
-    hDrawingDC = CreateCompatibleDC(GetDC(hImageArea));
-    hSelDC     = CreateCompatibleDC(GetDC(hImageArea));
+    hDC = GetDC(hImageArea);
+    hDrawingDC = CreateCompatibleDC(hDC);
+    hSelDC     = CreateCompatibleDC(hDC);
+    ReleaseDC(hImageArea, hDC);
     SelectObject(hDrawingDC, CreatePen(PS_SOLID, 0, fgColor));
     SelectObject(hDrawingDC, CreateSolidBrush(bgColor));
 
index 4f5c130..9165291 100644 (file)
@@ -25,6 +25,34 @@ placeSelWin()
     //SendMessage(hSelection, WM_PAINT, 0, 0);
 }
 
+void
+regularize(short x0, short y0, short *x1, short *y1)
+{
+    if (abs(*x1 - x0) >= abs(*y1 - y0))
+        *y1 = y0 + (*y1 > y0 ? abs(*x1 - x0) : -abs(*x1 - x0));
+    else
+        *x1 = x0 + (*x1 > x0 ? abs(*y1 - y0) : -abs(*y1 - y0));
+}
+
+void
+roundTo8Directions(short x0, short y0, short *x1, short *y1)
+{
+    if (abs(*x1 - x0) >= abs(*y1 - y0))
+    {
+        if (abs(*y1 - y0) * 5 < abs(*x1 - x0) * 2)
+            *y1 = y0;
+        else
+            *y1 = y0 + (*y1 > y0 ? abs(*x1 - x0) : -abs(*x1 - x0));
+    }
+    else
+    {
+        if (abs(*x1 - x0) * 5 < abs(*y1 - y0) * 2)
+            *x1 = x0;
+        else
+            *x1 = x0 + (*x1 > x0 ? abs(*y1 - y0) : -abs(*y1 - y0));
+    }
+}
+
 POINT pointStack[256];
 short pointSP;
 POINT *ptStack = NULL;
@@ -147,6 +175,8 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg)
             break;
         case 11:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                roundTo8Directions(startX, startY, &x, &y);
             Line(hdc, startX, startY, x, y, fg, lineWidth);
             break;
         case 12:
@@ -169,21 +199,30 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg)
             break;
         case 13:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             Rect(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle);
             break;
         case 14:
             resetToU1();
             pointStack[pointSP].x = x;
             pointStack[pointSP].y = y;
+            if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
+                roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
+                                   (short *)&pointStack[pointSP].x, (short *)&pointStack[pointSP].y);
             if (pointSP + 1 >= 2)
                 Poly(hdc, pointStack, pointSP + 1, fg, bg, lineWidth, shapeStyle, FALSE);
             break;
         case 15:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             Ellp(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle);
             break;
         case 16:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             RRect(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle);
             break;
     }
@@ -276,6 +315,8 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg)
             break;
         case 11:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                roundTo8Directions(startX, startY, &x, &y);
             Line(hdc, startX, startY, x, y, fg, lineWidth);
             break;
         case 12:
@@ -285,12 +326,17 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg)
             break;
         case 13:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             Rect(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle);
             break;
         case 14:
             resetToU1();
             pointStack[pointSP].x = x;
             pointStack[pointSP].y = y;
+            if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
+                roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
+                                   (short *)&pointStack[pointSP].x, (short *)&pointStack[pointSP].y);
             pointSP++;
             if (pointSP >= 2)
             {
@@ -310,10 +356,14 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg)
             break;
         case 15:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             Ellp(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle);
             break;
         case 16:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             RRect(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle);
             break;
     }
@@ -398,6 +448,8 @@ whilePaintingR(HDC hdc, short x, short y, int fg, int bg)
             break;
         case 11:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                roundTo8Directions(startX, startY, &x, &y);
             Line(hdc, startX, startY, x, y, bg, lineWidth);
             break;
         case 12:
@@ -420,21 +472,30 @@ whilePaintingR(HDC hdc, short x, short y, int fg, int bg)
             break;
         case 13:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             Rect(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle);
             break;
         case 14:
             resetToU1();
             pointStack[pointSP].x = x;
             pointStack[pointSP].y = y;
+            if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
+                roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
+                                   (short *)&pointStack[pointSP].x, (short *)&pointStack[pointSP].y);
             if (pointSP + 1 >= 2)
                 Poly(hdc, pointStack, pointSP + 1, bg, fg, lineWidth, shapeStyle, FALSE);
             break;
         case 15:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             Ellp(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle);
             break;
         case 16:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             RRect(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle);
             break;
     }
@@ -457,6 +518,8 @@ endPaintingR(HDC hdc, short x, short y, int fg, int bg)
             break;
         case 11:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                roundTo8Directions(startX, startY, &x, &y);
             Line(hdc, startX, startY, x, y, bg, lineWidth);
             break;
         case 12:
@@ -466,12 +529,17 @@ endPaintingR(HDC hdc, short x, short y, int fg, int bg)
             break;
         case 13:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             Rect(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle);
             break;
         case 14:
             resetToU1();
             pointStack[pointSP].x = x;
             pointStack[pointSP].y = y;
+            if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
+                roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
+                                   (short *)&pointStack[pointSP].x, (short *)&pointStack[pointSP].y);
             pointSP++;
             if (pointSP >= 2)
             {
@@ -491,10 +559,14 @@ endPaintingR(HDC hdc, short x, short y, int fg, int bg)
             break;
         case 15:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             Ellp(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle);
             break;
         case 16:
             resetToU1();
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                regularize(startX, startY, &x, &y);
             RRect(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle);
             break;
     }
index 066b3ba..bc83f3a 100644 (file)
@@ -1,3 +1,5 @@
+<?xml version="1.0"?>
+<!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">
 <group>
 <module name="rapps" type="win32gui" installbase="system32" installname="rapps.exe" unicode="yes">
        <include base="ReactOS">include/reactos</include>
index e605180..e9313b7 100644 (file)
@@ -2,41 +2,41 @@
 
 [Section]
 Name = Mozilla Firefox 3.0
-Version = 3.0.18
+Version = 3.0.19
 Licence = MPL/GPL/LGPL
 Description = The most popular and one of the best free Web Browsers out there.
 Size = 7.2M
 Category = 5
 URLSite = http://www.mozilla.com/en-US/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/en-US/Firefox%20Setup%203.0.18.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/en-US/Firefox%20Setup%203.0.19.exe
 CDPath = none
 
 [Section.0407]
 Description = Der populärste und einer der besten freien Webbrowser.
 Size = 7.0M
 URLSite = http://www.mozilla-europe.org/de/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/de/Firefox%20Setup%203.0.18.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/de/Firefox%20Setup%203.0.19.exe
 
 [Section.040a]
 Description = El más popular y uno de los mejores navegadores web gratuitos que hay.
 Size = 7.0M
 URLSite = http://www.mozilla-europe.org/es/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/es-ES/Firefox%20Setup%203.0.18.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/es-ES/Firefox%20Setup%203.0.19.exe
 
 [Section.0414]
 Description = Mest populære og best også gratis nettleserene der ute.
-Size = 6.9M
+Size = 7.0M
 URLSite = http://www.mozilla-europe.org/no/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/nb-NO/Firefox%20Setup%203.0.18.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/nb-NO/Firefox%20Setup%203.0.19.exe
 
 [Section.0415]
 Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych.
 Size = 7.8M
 URLSite = http://www.mozilla-europe.org/pl/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/pl/Firefox%20Setup%203.0.18.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/pl/Firefox%20Setup%203.0.19.exe
 
 [Section.0419]
 Description = Один из самых популярных и лучших бесплатных браузеров.
 Size = 7.4M
 URLSite = http://www.mozilla-europe.org/ru/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/ru/Firefox%20Setup%203.0.18.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/ru/Firefox%20Setup%203.0.19.exe
index 0fff6a4..e1f6628 100644 (file)
@@ -2,13 +2,13 @@
 
 [Section]
 Name = Miranda IM
-Version = 0.8.18
+Version = 0.8.21
 Licence = GPL
 Description = Open source multiprotocol instant messaging application - May not work completely.
 Size = 1.6MB
 Category = 5
 URLSite = http://www.miranda-im.org/
-URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.18-unicode.exe
+URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.21-unicode.exe
 CDPath = none
 
 [Section.0407]
index dfc94a9..2e70160 100644 (file)
@@ -2,13 +2,13 @@
 
 [Section]
 Name = OpenTTD
-Version = 0.7.5
+Version = 1.0.0
 Licence = GPL v2
 Description = Open Source clone of the "Transport Tycoon Deluxe" game engine. You need a copy of Transport Tycoon.
-Size = 2.9MB
+Size = 3.5MB
 Category = 4
 URLSite = http://www.openttd.org/
-URLDownload = http://binaries.openttd.org/releases/0.7.5/openttd-0.7.5-windows-win32.exe
+URLDownload = http://binaries.openttd.org/releases/1.0.0/openttd-1.0.0-windows-win32.exe
 CDPath = none
 
 [Section.0407]
index 44e49cc..aee4c21 100644 (file)
@@ -2,13 +2,13 @@
 
 [Section]
 Name = Opera
-Version = 10.51
+Version = 10.52
 Licence = Freeware
 Description = The popular Opera Browser with many advanced features and including a Mail and BitTorrent client.
-Size = 11.0M
+Size = 12.0M
 Category = 5
 URLSite = http://www.opera.com/
-URLDownload = http://get4.opera.com/pub/opera/win/1051/int/Opera_1051_int_Setup.exe
+URLDownload = http://get4.opera.com/pub/opera/win/1052/int/Opera_1052_int_Setup.exe
 CDPath = none
 
 [Section.0407]
index fc3d9d5..c32df9c 100644 (file)
@@ -2,13 +2,13 @@
 
 [Section]
 Name = SciTE
-Version = 2.03
+Version = 2.11
 Licence = Freeware
 Description = SciTE is a SCIntilla based Text Editor. Originally built to demonstrate Scintilla, it has grown to be a generally useful editor with facilities for building and running programs.
 Size = 0.6M
 Category = 7
 URLSite = http://www.scintilla.org/
-URLDownload = http://ovh.dl.sourceforge.net/sourceforge/scintilla/Sc203.exe
+URLDownload = http://ovh.dl.sourceforge.net/sourceforge/scintilla/Sc211.exe
 CDPath = none
 
 [Section.0407]
index 6365b1c..ebe7b34 100644 (file)
@@ -2,13 +2,13 @@
 
 [Section]
 Name = ScummVM
-Version = 1.0.0
+Version = 1.1.0
 Licence = GPL
 Description = Sam and Max, Day of the Tentacle, etc on ReactOS.
-Size = 3.1MB
+Size = 3.4MB
 Category = 4
 URLSite = http://scummvm.org/
-URLDownload = http://dfn.dl.sourceforge.net/project/scummvm/scummvm/1.0.0/scummvm-1.0.0-win32.exe
+URLDownload = http://dfn.dl.sourceforge.net/project/scummvm/scummvm/1.1.0/scummvm-1.1.0-win32.exe
 CDPath = none
 
 [Section.0407]
index 9c980d3..55d3be8 100644 (file)
@@ -2,31 +2,31 @@
 
 [Section]
 Name = Mozilla SeaMonkey
-Version = 2.0.3
+Version = 2.0.4
 Licence = MPL/GPL/LGPL
 Description = Mozilla Suite is alive. This is the one and only Browser, Mail, Chat, and Composer bundle you will ever need.
-Size = 10.0MB
+Size = 10.1MB
 Category = 5
 URLSite = http://www.seamonkey-project.org/
-URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/en-US/SeaMonkey%20Setup%202.0.3.exe
+URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.4/win32/en-US/SeaMonkey%20Setup%202.0.4.exe
 CDPath = none
 
 [Section.0407]
 Description = Mozilla Suite lebt. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen.
-Size = 10.1MB
-URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/de/SeaMonkey%20Setup%202.0.3.exe
+Size = 10.0MB
+URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.4/win32/de/SeaMonkey%20Setup%202.0.4.exe
 
 [Section.040a]
 Description = La suite de Mozilla está viva. Es el primero y único navegador web, gestor de correo, lector de noticias, Chat y editor HTML que necesitarás.
 Size = 10.0MB
-URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/es-ES/SeaMonkey%20Setup%202.0.3.exe
+URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.4/win32/es-ES/SeaMonkey%20Setup%202.0.4.exe
 
 [Section.0415]
 Description = Pakiet Mozilla żyje. W zestawie: przeglądarka, klient poczty, IRC oraz Edytor HTML - wszystko, czego potrzebujesz.
 Size = 10.8MB
-URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/pl/SeaMonkey%20Setup%202.0.3.exe
+URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.4/win32/pl/SeaMonkey%20Setup%202.0.4.exe
 
 [Section.0419]
 Description = Продолжение Mozilla Suite. Включает браузер, почтовый клиент, IRC-клиент и HTML-редактор.
 Size = 10.4MB
-URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/ru/SeaMonkey%20Setup%202.0.3.exe
+URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.4/win32/ru/SeaMonkey%20Setup%202.0.4.exe
index 9f0cd32..a9e837c 100644 (file)
@@ -2,35 +2,35 @@
 
 [Section]
 Name = Mozilla Thunderbird
-Version = 3.0.3
+Version = 3.0.4
 Licence = MPL/GPL/LGPL
 Description = The most popular and one of the best free Mail Clients out there.
 Size = 8.6M
 Category = 5
 URLSite = http://www.mozilla-europe.org/en/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/en-US/Thunderbird%20Setup%203.0.3.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.4/win32/en-US/Thunderbird%20Setup%203.0.4.exe
 CDPath = none
 
 [Section.0407]
 Description = Der populärste und einer der besten freien Mail-Clients.
-Size = 8.4M
+Size = 8.5M
 URLSite = http://www.mozilla-europe.org/de/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/de/Thunderbird%20Setup%203.0.3.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.4/win32/de/Thunderbird%20Setup%203.0.4.exe
 
 [Section.040a]
 Description = El más popular y uno de los mejores clientes mail que hay.
 Size = 8.4M
 URLSite = http://www.mozilla-europe.org/es/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/es-ES/Thunderbird%20Setup%203.0.3.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.4/win32/es-ES/Thunderbird%20Setup%203.0.4.exe
 
 [Section.0415]
 Description = Najpopularniejszy i jeden z najlepszych darmowych klientów poczty.
 Size = 9.3M
 URLSite = http://www.mozilla-europe.org/pl/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/pl/Thunderbird%20Setup%203.0.3.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.4/win32/pl/Thunderbird%20Setup%203.0.4.exe
 
 [Section.0419]
 Description = Один из самых популярных и лучших бесплатных почтовых клиентов.
 Size = 8.8M
 URLSite = http://www.mozilla-europe.org/ru/products/thunderbird/
-URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/ru/Thunderbird%20Setup%203.0.3.exe
+URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.4/win32/ru/Thunderbird%20Setup%203.0.4.exe
index 9882637..ffcded7 100644 (file)
@@ -2,13 +2,13 @@
 
 [Section]
 Name = µTorrent
-Version = 2.0
+Version = 2.0.1
 Licence = Freeware for non-commercial uses
 Description = Small and fast BitTorrent Client.
-Size = 312K
+Size = 314K
 Category = 5
 URLSite = http://www.utorrent.com/
-URLDownload = http://download.utorrent.com/2.0/utorrent.exe
+URLDownload = http://download.utorrent.com/2.0.1/utorrent.exe
 CDPath = none
 
 
index 6a90cc3..a6b4144 100644 (file)
@@ -228,8 +228,6 @@ static BOOL CheckCommDlgError(HWND hWnd)
     return TRUE;
 }
 
-#define MAX_CUSTOM_FILTER_SIZE 50
-TCHAR CustomFilterBuffer[MAX_CUSTOM_FILTER_SIZE];
 TCHAR FileNameBuffer[_MAX_PATH];
 TCHAR FileTitleBuffer[_MAX_PATH];
 
@@ -275,25 +273,11 @@ static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
     BuildFilterStrings(Filter, FilterPairs, sizeof(FilterPairs) / sizeof(FILTERPAIR));
 
     pofn->lpstrFilter = Filter;
-    pofn->lpstrCustomFilter = CustomFilterBuffer;
-    pofn->nMaxCustFilter = MAX_CUSTOM_FILTER_SIZE;
-    pofn->nFilterIndex = 0;
     pofn->lpstrFile = FileNameBuffer;
     pofn->nMaxFile = _MAX_PATH;
     pofn->lpstrFileTitle = FileTitleBuffer;
     pofn->nMaxFileTitle = _MAX_PATH;
-    /*    pofn->lpstrInitialDir = _T("");*/
-    /*    pofn->lpstrTitle = _T("Import Registry File");*/
-    /*    pofn->Flags = OFN_ENABLETEMPLATE + OFN_EXPLORER + OFN_ENABLESIZING;*/
     pofn->Flags = OFN_HIDEREADONLY;
-    /*    pofn->nFileOffset = ;*/
-    /*    pofn->nFileExtension = ;*/
-    /*    pofn->lpstrDefExt = _T("");*/
-    /*    pofn->lCustData = ;*/
-    /*    pofn->lpfnHook = ImportRegistryFile_OFNHookProc;*/
-    /*    pofn->lpTemplateName = _T("ID_DLG_IMPORT_REGFILE");*/
-    /*    pofn->lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG1);*/
-    /*    pofn->FlagsEx = ;*/
     return TRUE;
 }
 
@@ -356,11 +340,11 @@ static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, W
 
         hwndExportAll = GetDlgItem(hdlg, IDC_EXPORT_ALL);
         if (hwndExportAll)
-                       SendMessage(hwndExportAll, BM_SETCHECK, pszSelectedKey[0] ? BST_UNCHECKED : BST_CHECKED, 0);
+            SendMessage(hwndExportAll, BM_SETCHECK, pszSelectedKey ? BST_UNCHECKED : BST_CHECKED, 0);
 
         hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
         if (hwndExportBranch)
-            SendMessage(hwndExportBranch, BM_SETCHECK, pszSelectedKey[0] ? BST_CHECKED : BST_UNCHECKED, 0);
+            SendMessage(hwndExportBranch, BM_SETCHECK, pszSelectedKey ? BST_CHECKED : BST_UNCHECKED, 0);
 
         hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
         if (hwndExportBranchText)
@@ -406,7 +390,12 @@ BOOL ExportRegistryFile(HWND hWnd)
     InitOpenFileName(hWnd, &ofn);
     LoadString(hInst, IDS_EXPORT_REG_FILE, Caption, sizeof(Caption)/sizeof(TCHAR));
     ofn.lpstrTitle = Caption;
-    ofn.lCustData = (LPARAM) ExportKeyPath;
+
+    /* Only set the path if a key (not the root node) is selected */
+    if (hKeyRoot != 0)
+    {
+        ofn.lCustData = (LPARAM) ExportKeyPath;
+    }
     ofn.Flags = OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLEHOOK;
     ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
     ofn.lpTemplateName = MAKEINTRESOURCE(IDD_EXPORTRANGE);
index 3ef6ee9..0c20e81 100644 (file)
@@ -49,7 +49,7 @@ void            ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam);
 void            ApplicationPageShowContextMenu1(void);
 void            ApplicationPageShowContextMenu2(void);
 int CALLBACK    ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
-int             PerfGetIndexByProcessId(DWORD dwProcessId);
+int             ProcGetIndexByProcessId(DWORD dwProcessId);
 
 #if 0
 void SwitchToThisWindow (
@@ -236,6 +236,13 @@ void UpdateApplicationListControlViewSetting(void)
 
 DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter)
 {
+    INT i;
+    BOOL                            bItemRemoved = FALSE;
+    LV_ITEM                         item;
+    LPAPPLICATION_PAGE_LIST_ITEM    pAPLI = NULL;
+    HIMAGELIST                      hImageListLarge;
+    HIMAGELIST                      hImageListSmall;
+
     /* Create the event */
     hApplicationPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
 
@@ -269,6 +276,55 @@ DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter)
             EnumWindows(EnumWindowsProc, 0);
             if (noApps)
                 (void)ListView_DeleteAllItems(hApplicationPageListCtrl);
+
+            /* Get the image lists */
+            hImageListLarge = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_NORMAL);
+            hImageListSmall = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_SMALL);
+
+            /* Check to see if we need to remove any items from the list */
+            for (i=ListView_GetItemCount(hApplicationPageListCtrl)-1; i>=0; i--)
+            {
+                memset(&item, 0, sizeof(LV_ITEM));
+                item.mask = LVIF_IMAGE|LVIF_PARAM;
+                item.iItem = i;
+                (void)ListView_GetItem(hApplicationPageListCtrl, &item);
+
+                pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
+                if (!IsWindow(pAPLI->hWnd)||
+                    (wcslen(pAPLI->szTitle) <= 0) ||
+                    !IsWindowVisible(pAPLI->hWnd) ||
+                    (GetParent(pAPLI->hWnd) != NULL) ||
+                    (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) ||
+                    (GetWindowLongPtr(pAPLI->hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
+                {
+                    ImageList_Remove(hImageListLarge, item.iItem);
+                    ImageList_Remove(hImageListSmall, item.iItem);
+
+                    (void)ListView_DeleteItem(hApplicationPageListCtrl, item.iItem);
+                    HeapFree(GetProcessHeap(), 0, pAPLI);
+                    bItemRemoved = TRUE;
+                }
+            }
+
+            /*
+             * If an item was removed from the list then
+             * we need to resync all the items with the
+             * image list
+             */
+            if (bItemRemoved)
+            {
+                for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++)
+                {
+                    memset(&item, 0, sizeof(LV_ITEM));
+                    item.mask = LVIF_IMAGE;
+                    item.iItem = i;
+                    item.iImage = i;
+                    (void)ListView_SetItem(hApplicationPageListCtrl, &item);
+                }
+                bItemRemoved = FALSE;
+            }
+
+            ApplicationPageUpdate();
         }
     }
 }
@@ -333,13 +389,12 @@ BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
 
 void AddOrUpdateHwnd(HWND hWnd, WCHAR *szTitle, HICON hIcon, BOOL bHung)
 {
-    LPAPPLICATION_PAGE_LIST_ITEM  pAPLI = NULL;
-    HIMAGELIST                    hImageListLarge;
-    HIMAGELIST                    hImageListSmall;
-    LV_ITEM                       item;
-    int                           i;
-    BOOL                          bAlreadyInList = FALSE;
-    BOOL                          bItemRemoved = FALSE;
+    LPAPPLICATION_PAGE_LIST_ITEM    pAPLI = NULL;
+    HIMAGELIST                      hImageListLarge;
+    HIMAGELIST                      hImageListSmall;
+    LV_ITEM                         item;
+    int                             i;
+    BOOL                            bAlreadyInList = FALSE;
 
     memset(&item, 0, sizeof(LV_ITEM));
 
@@ -406,51 +461,7 @@ void AddOrUpdateHwnd(HWND hWnd, WCHAR *szTitle, HICON hIcon, BOOL bHung)
         item.lParam = (LPARAM)pAPLI;
         (void)ListView_InsertItem(hApplicationPageListCtrl, &item);
     }
-
-
-    /* Check to see if we need to remove any items from the list */
-    for (i=ListView_GetItemCount(hApplicationPageListCtrl)-1; i>=0; i--)
-    {
-        memset(&item, 0, sizeof(LV_ITEM));
-        item.mask = LVIF_IMAGE|LVIF_PARAM;
-        item.iItem = i;
-        (void)ListView_GetItem(hApplicationPageListCtrl, &item);
-
-        pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
-        if (!IsWindow(pAPLI->hWnd)||
-            (wcslen(pAPLI->szTitle) <= 0) ||
-            !IsWindowVisible(pAPLI->hWnd) ||
-            (GetParent(pAPLI->hWnd) != NULL) ||
-            (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) ||
-            (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
-        {
-            ImageList_Remove(hImageListLarge, item.iItem);
-            ImageList_Remove(hImageListSmall, item.iItem);
-
-            (void)ListView_DeleteItem(hApplicationPageListCtrl, item.iItem);
-            HeapFree(GetProcessHeap(), 0, pAPLI);
-            bItemRemoved = TRUE;
-        }
-    }
-
-    /*
-     * If an item was removed from the list then
-     * we need to resync all the items with the
-     * image list
-     */
-    if (bItemRemoved)
-    {
-        for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++)
-        {
-            memset(&item, 0, sizeof(LV_ITEM));
-            item.mask = LVIF_IMAGE;
-            item.iItem = i;
-            item.iImage = i;
-            (void)ListView_SetItem(hApplicationPageListCtrl, &item);
-        }
-    }
-
-    ApplicationPageUpdate();
+    return;
 }
 
 void ApplicationPageUpdate(void)
@@ -878,7 +889,6 @@ void ApplicationPage_OnGotoProcess(void)
     LPAPPLICATION_PAGE_LIST_ITEM  pAPLI = NULL;
     LV_ITEM                       item;
     int                           i;
-    /* NMHDR nmhdr; */
 
     for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
         memset(&item, 0, sizeof(LV_ITEM));
@@ -902,7 +912,7 @@ void ApplicationPage_OnGotoProcess(void)
         /*
          * Select the process item in the list
          */
-        i = PerfGetIndexByProcessId(dwProcessId);
+        i = ProcGetIndexByProcessId(dwProcessId);
         if (i != -1)
         {
             ListView_SetItemState(hProcessPageListCtrl,
index 015c499..a1095e5 100644 (file)
@@ -40,6 +40,15 @@ SYSTEM_HANDLE_INFORMATION                  SystemHandleInfo;
 PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION  SystemProcessorTimeInfo = NULL;
 PSID                                       SystemUserSid = NULL;
 
+typedef struct _SIDTOUSERNAME
+{
+    LIST_ENTRY List;
+    LPWSTR pszName;
+    BYTE Data[0];
+} SIDTOUSERNAME, *PSIDTOUSERNAME;
+
+static LIST_ENTRY SidToUserNameHead = {&SidToUserNameHead, &SidToUserNameHead};
+
 BOOL PerfDataInitialize(void)
 {
     SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
@@ -63,6 +72,8 @@ BOOL PerfDataInitialize(void)
 
 void PerfDataUninitialize(void)
 {
+    PLIST_ENTRY pCur;
+    PSIDTOUSERNAME pEntry;
 
     if (pPerfData != NULL)
         HeapFree(GetProcessHeap(), 0, pPerfData);
@@ -74,6 +85,15 @@ void PerfDataUninitialize(void)
         FreeSid(SystemUserSid);
         SystemUserSid = NULL;
     }
+
+    /* Free user names cache list */
+    pCur = SidToUserNameHead.Flink;
+    while (pCur != &SidToUserNameHead)
+    {
+        pEntry = CONTAINING_RECORD(pCur, SIDTOUSERNAME, List);
+        pCur = pCur->Flink;
+        HeapFree(GetProcessHeap(), 0, pEntry);
+    }
 }
 
 static void SidToUserName(PSID Sid, LPWSTR szBuffer, DWORD BufferSize)
@@ -86,6 +106,56 @@ static void SidToUserName(PSID Sid, LPWSTR szBuffer, DWORD BufferSize)
         LookupAccountSidW(NULL, Sid, szBuffer, &BufferSize, szDomainNameUnused, &DomainNameLen, &Use);
 }
 
+VOID
+WINAPI
+CachedGetUserFromSid(
+    PSID pSid,
+    LPWSTR pUserName,
+    PULONG pcwcUserName)
+{
+    PLIST_ENTRY pCur;
+    PSIDTOUSERNAME pEntry;
+    ULONG cbSid, cwcUserName;
+
+    cwcUserName = *pcwcUserName;
+
+    /* Walk through the list */
+    for(pCur = SidToUserNameHead.Flink;
+        pCur != &SidToUserNameHead;
+        pCur = pCur->Flink)
+    {
+        pEntry = CONTAINING_RECORD(pCur, SIDTOUSERNAME, List);
+        if (EqualSid((PSID)&pEntry->Data, pSid))
+        {
+            wcsncpy(pUserName, pEntry->pszName, cwcUserName);
+            *pcwcUserName = cwcUserName;
+            return;
+        }
+    }
+
+    /* We didn't find the SID in the list, get the name conventional */
+    SidToUserName(pSid, pUserName, cwcUserName);
+
+    /* Allocate a new entry */
+    *pcwcUserName = wcslen(pUserName);
+    cwcUserName = *pcwcUserName + 1;
+    cbSid = GetLengthSid(pSid);
+    pEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(SIDTOUSERNAME) + cbSid + cwcUserName * sizeof(WCHAR));
+
+    /* Copy the Sid and name to our entry */
+    CopySid(cbSid, (PSID)&pEntry->Data, pSid);
+    pEntry->pszName = (LPWSTR)(pEntry->Data + cbSid);
+    wcsncpy(pEntry->pszName, pUserName, cwcUserName);
+
+    /* Insert the new entry */
+    pEntry->List.Flink = &SidToUserNameHead;
+    pEntry->List.Blink = SidToUserNameHead.Blink;
+    SidToUserNameHead.Blink->Flink = &pEntry->List;
+    SidToUserNameHead.Blink = &pEntry->List;
+
+    return;
+}
+
 void PerfDataRefresh(void)
 {
     ULONG                                      ulSize;
@@ -106,6 +176,7 @@ void PerfDataRefresh(void)
     PSECURITY_DESCRIPTOR                       ProcessSD;
     PSID                                       ProcessUser;
     ULONG                                      Buffer[64]; /* must be 4 bytes aligned! */
+    ULONG                                      cwcUserName;
 
     /* Get new system time */
     status = NtQuerySystemInformation(SystemTimeOfDayInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
@@ -341,7 +412,8 @@ ClearInfo:
             ZeroMemory(&pPerfData[Idx].IOCounters, sizeof(IO_COUNTERS));
         }
 
-        SidToUserName(ProcessUser, pPerfData[Idx].UserName, sizeof(pPerfData[0].UserName) / sizeof(pPerfData[0].UserName[0]));
+        cwcUserName = sizeof(pPerfData[0].UserName) / sizeof(pPerfData[0].UserName[0]);
+        CachedGetUserFromSid(ProcessUser, pPerfData[Idx].UserName, &cwcUserName);
 
         if (ProcessSD != NULL)
         {
@@ -356,6 +428,29 @@ ClearInfo:
     LeaveCriticalSection(&PerfDataCriticalSection);
 }
 
+ULONG PerfDataGetProcessIndex(ULONG pid)
+{
+    ULONG idx;
+
+    EnterCriticalSection(&PerfDataCriticalSection);
+
+    for (idx = 0; idx < ProcessCount; idx++)
+    {
+        if (PtrToUlong(pPerfData[idx].ProcessId) == pid)
+        {
+            break;
+        }
+    }
+
+    LeaveCriticalSection(&PerfDataCriticalSection);
+
+    if (idx == ProcessCount)
+    {
+        return -1;
+    }
+    return idx;
+}
+
 ULONG PerfDataGetProcessCount(void)
 {
     return ProcessCount;
@@ -387,27 +482,6 @@ BOOL PerfDataGetImageName(ULONG Index, LPWSTR lpImageName, int nMaxCount)
     return bSuccessful;
 }
 
-int PerfGetIndexByProcessId(DWORD dwProcessId)
-{
-    int FoundIndex = -1;
-    ULONG Index;
-
-    EnterCriticalSection(&PerfDataCriticalSection);
-
-    for (Index = 0; Index < ProcessCount; Index++)
-    {
-        if (PtrToUlong(pPerfData[Index].ProcessId) == dwProcessId)
-        {
-            FoundIndex = Index;
-            break;
-        }
-    }
-
-    LeaveCriticalSection(&PerfDataCriticalSection);
-
-    return FoundIndex;
-}
-
 ULONG PerfDataGetProcessId(ULONG Index)
 {
     ULONG  ProcessId;
index 00c2d6d..6bb7005 100644 (file)
@@ -60,6 +60,7 @@ void  PerfDataUninitialize(void);
 void   PerfDataRefresh(void);
 
 BOOL    PerfDataGet(ULONG Index, PPERFDATA *lppData);
+ULONG   PerfDataGetProcessIndex(ULONG pid);
 ULONG  PerfDataGetProcessCount(void);
 ULONG  PerfDataGetProcessorUsage(void);
 ULONG  PerfDataGetProcessorSystemUsage(void);
index 4c3b636..42bf594 100644 (file)
@@ -28,7 +28,6 @@
 
 typedef struct
 {
-    ULONG Index;
     ULONG ProcessId;
 } PROCESS_PAGE_LIST_ITEM, *LPPROCESS_PAGE_LIST_ITEM;
 
@@ -54,6 +53,27 @@ BOOL PerfDataGetText(ULONG Index, ULONG ColumnIndex, LPTSTR lpText, int nMaxCoun
 DWORD WINAPI ProcessPageRefreshThread(void *lpParameter);
 int ProcessRunning(ULONG ProcessId);
 
+int ProcGetIndexByProcessId(DWORD dwProcessId)
+{
+    int     i;
+    LVITEM  item;
+    LPPROCESS_PAGE_LIST_ITEM pData;
+
+    for (i=0; i<ListView_GetItemCount(hProcessPageListCtrl); i++)
+    {
+        memset(&item, 0, sizeof(LV_ITEM));
+        item.mask = LVIF_PARAM;
+        item.iItem = i;
+        (void)ListView_GetItem(hProcessPageListCtrl, &item);
+        pData = (LPPROCESS_PAGE_LIST_ITEM)item.lParam;
+        if (pData->ProcessId == dwProcessId)
+        {
+            return i;
+        }
+    }
+    return 0;
+}
+
 DWORD GetSelectedProcessId(void)
 {
     int     Index;
@@ -71,7 +91,7 @@ DWORD GetSelectedProcessId(void)
         (void)ListView_GetItem(hProcessPageListCtrl, &lvitem);
 
         if (lvitem.lParam)
-            return PerfDataGetProcessId(((LPPROCESS_PAGE_LIST_ITEM)lvitem.lParam)->Index);
+            return ((LPPROCESS_PAGE_LIST_ITEM)lvitem.lParam)->ProcessId;
     }
 
     return 0;
@@ -219,7 +239,7 @@ void ProcessPageOnNotify(WPARAM wParam, LPARAM lParam)
                 break;
 
             pData = (LPPROCESS_PAGE_LIST_ITEM)pnmdi->item.lParam;
-            Index = pData->Index;
+            Index = PerfDataGetProcessIndex(pData->ProcessId);
             ColumnIndex = pnmdi->item.iSubItem;
 
             PerfDataGetText(Index, ColumnIndex, pnmdi->item.pszText, pnmdi->item.cchTextMax);
@@ -414,7 +434,7 @@ void UpdateProcesses()
 {
     int i;
     ULONG l;
-    LV_ITEM    item;
+    LV_ITEM item;
     LPPROCESS_PAGE_LIST_ITEM pData;
 
     /* Remove old processes */
@@ -431,10 +451,17 @@ void UpdateProcesses()
             HeapFree(GetProcessHeap(), 0, pData);
         }
     }
-    for (l = 0; l < PerfDataGetProcessCount(); l++)
+
+    /* Check for difference in listview process and performance process counts */
+    if (ListView_GetItemCount(hProcessPageListCtrl) != PerfDataGetProcessCount())
     {
-        AddProcess(l);
+        /* Add new processes by checking against the current items */
+        for (l = 0; l < PerfDataGetProcessCount(); l++)
+        {
+            AddProcess(l);
+        }
     }
+
     if (TaskManagerSettings.SortColumn != -1)
     {
         (void)ListView_SortItems(hProcessPageListCtrl, ProcessPageCompareFunc, NULL);
@@ -482,7 +509,7 @@ void AddProcess(ULONG Index)
         item.iItem = i;
         (void)ListView_GetItem(hProcessPageListCtrl, &item);
         pData = (LPPROCESS_PAGE_LIST_ITEM)item.lParam;
-        if (PerfDataGetProcessId(pData->Index) == pid)
+        if (pData->ProcessId == pid)
         {
             bAlreadyInList = TRUE;
             break;
@@ -491,7 +518,6 @@ void AddProcess(ULONG Index)
     if (!bAlreadyInList)  /* Add */
     {
         pData = (LPPROCESS_PAGE_LIST_ITEM)HeapAlloc(GetProcessHeap(), 0, sizeof(PROCESS_PAGE_LIST_ITEM));
-        pData->Index = Index;
         pData->ProcessId = pid;
 
         /* Add the item to the list */
@@ -686,6 +712,8 @@ int CALLBACK ProcessPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lPara
     int ret = 0;
     LPPROCESS_PAGE_LIST_ITEM Param1;
     LPPROCESS_PAGE_LIST_ITEM Param2;
+    ULONG IndexParam1;
+    ULONG IndexParam2;
     WCHAR text1[260];
     WCHAR text2[260];
     ULONG l1;
@@ -704,165 +732,167 @@ int CALLBACK ProcessPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lPara
         Param1 = (LPPROCESS_PAGE_LIST_ITEM)lParam2;
         Param2 = (LPPROCESS_PAGE_LIST_ITEM)lParam1;
     }
+    IndexParam1 = PerfDataGetProcessIndex(Param1->ProcessId);
+    IndexParam2 = PerfDataGetProcessIndex(Param2->ProcessId);
 
     if (TaskManagerSettings.SortColumn == COLUMN_IMAGENAME)
     {
-        PerfDataGetImageName(Param1->Index, text1, sizeof (text1) / sizeof (*text1));
-        PerfDataGetImageName(Param2->Index, text2, sizeof (text2) / sizeof (*text2));
+        PerfDataGetImageName(IndexParam1, text1, sizeof (text1) / sizeof (*text1));
+        PerfDataGetImageName(IndexParam2, text2, sizeof (text2) / sizeof (*text2));
         ret = _wcsicmp(text1, text2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_PID)
     {
-        l1 = PerfDataGetProcessId(Param1->Index);
-        l2 = PerfDataGetProcessId(Param2->Index);
+        l1 = Param1->ProcessId;
+        l2 = Param2->ProcessId;
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_USERNAME)
     {
-        PerfDataGetUserName(Param1->Index, text1, sizeof (text1) / sizeof (*text1));
-        PerfDataGetUserName(Param2->Index, text2, sizeof (text2) / sizeof (*text2));
+        PerfDataGetUserName(IndexParam1, text1, sizeof (text1) / sizeof (*text1));
+        PerfDataGetUserName(IndexParam2, text2, sizeof (text2) / sizeof (*text2));
         ret = _wcsicmp(text1, text2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_SESSIONID)
     {
-        l1 = PerfDataGetSessionId(Param1->Index);
-        l2 = PerfDataGetSessionId(Param2->Index);
+        l1 = PerfDataGetSessionId(IndexParam1);
+        l2 = PerfDataGetSessionId(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_CPUUSAGE)
     {
-        l1 = PerfDataGetCPUUsage(Param1->Index);
-        l2 = PerfDataGetCPUUsage(Param2->Index);
+        l1 = PerfDataGetCPUUsage(IndexParam1);
+        l2 = PerfDataGetCPUUsage(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_CPUTIME)
     {
-        time1 = PerfDataGetCPUTime(Param1->Index);
-        time2 = PerfDataGetCPUTime(Param2->Index);
+        time1 = PerfDataGetCPUTime(IndexParam1);
+        time2 = PerfDataGetCPUTime(IndexParam2);
         ret = largeintcmp(time1, time2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_MEMORYUSAGE)
     {
-        l1 = PerfDataGetWorkingSetSizeBytes(Param1->Index);
-        l2 = PerfDataGetWorkingSetSizeBytes(Param2->Index);
+        l1 = PerfDataGetWorkingSetSizeBytes(IndexParam1);
+        l2 = PerfDataGetWorkingSetSizeBytes(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_PEAKMEMORYUSAGE)
     {
-        l1 = PerfDataGetPeakWorkingSetSizeBytes(Param1->Index);
-        l2 = PerfDataGetPeakWorkingSetSizeBytes(Param2->Index);
+        l1 = PerfDataGetPeakWorkingSetSizeBytes(IndexParam1);
+        l2 = PerfDataGetPeakWorkingSetSizeBytes(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_MEMORYUSAGEDELTA)
     {
-        l1 = PerfDataGetWorkingSetSizeDelta(Param1->Index);
-        l2 = PerfDataGetWorkingSetSizeDelta(Param2->Index);
+        l1 = PerfDataGetWorkingSetSizeDelta(IndexParam1);
+        l2 = PerfDataGetWorkingSetSizeDelta(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_PAGEFAULTS)
     {
-        l1 = PerfDataGetPageFaultCount(Param1->Index);
-        l2 = PerfDataGetPageFaultCount(Param2->Index);
+        l1 = PerfDataGetPageFaultCount(IndexParam1);
+        l2 = PerfDataGetPageFaultCount(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_PAGEFAULTSDELTA)
     {
-        l1 = PerfDataGetPageFaultCountDelta(Param1->Index);
-        l2 = PerfDataGetPageFaultCountDelta(Param2->Index);
+        l1 = PerfDataGetPageFaultCountDelta(IndexParam1);
+        l2 = PerfDataGetPageFaultCountDelta(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_VIRTUALMEMORYSIZE)
     {
-        l1 = PerfDataGetVirtualMemorySizeBytes(Param1->Index);
-        l2 = PerfDataGetVirtualMemorySizeBytes(Param2->Index);
+        l1 = PerfDataGetVirtualMemorySizeBytes(IndexParam1);
+        l2 = PerfDataGetVirtualMemorySizeBytes(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_PAGEDPOOL)
     {
-        l1 = PerfDataGetPagedPoolUsagePages(Param1->Index);
-        l2 = PerfDataGetPagedPoolUsagePages(Param2->Index);
+        l1 = PerfDataGetPagedPoolUsagePages(IndexParam1);
+        l2 = PerfDataGetPagedPoolUsagePages(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_NONPAGEDPOOL)
     {
-        l1 = PerfDataGetNonPagedPoolUsagePages(Param1->Index);
-        l2 = PerfDataGetNonPagedPoolUsagePages(Param2->Index);
+        l1 = PerfDataGetNonPagedPoolUsagePages(IndexParam1);
+        l2 = PerfDataGetNonPagedPoolUsagePages(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_BASEPRIORITY)
     {
-        l1 = PerfDataGetBasePriority(Param1->Index);
-        l2 = PerfDataGetBasePriority(Param2->Index);
+        l1 = PerfDataGetBasePriority(IndexParam1);
+        l2 = PerfDataGetBasePriority(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_HANDLECOUNT)
     {
-        l1 = PerfDataGetHandleCount(Param1->Index);
-        l2 = PerfDataGetHandleCount(Param2->Index);
+        l1 = PerfDataGetHandleCount(IndexParam1);
+        l2 = PerfDataGetHandleCount(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_THREADCOUNT)
     {
-        l1 = PerfDataGetThreadCount(Param1->Index);
-        l2 = PerfDataGetThreadCount(Param2->Index);
+        l1 = PerfDataGetThreadCount(IndexParam1);
+        l2 = PerfDataGetThreadCount(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_USEROBJECTS)
     {
-        l1 = PerfDataGetUSERObjectCount(Param1->Index);
-        l2 = PerfDataGetUSERObjectCount(Param2->Index);
+        l1 = PerfDataGetUSERObjectCount(IndexParam1);
+        l2 = PerfDataGetUSERObjectCount(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_GDIOBJECTS)
     {
-        l1 = PerfDataGetGDIObjectCount(Param1->Index);
-        l2 = PerfDataGetGDIObjectCount(Param2->Index);
+        l1 = PerfDataGetGDIObjectCount(IndexParam1);
+        l2 = PerfDataGetGDIObjectCount(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOREADS)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.ReadOperationCount;
         ull2 = iocounters2.ReadOperationCount;
         ret = CMP(ull1, ull2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOWRITES)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.WriteOperationCount;
         ull2 = iocounters2.WriteOperationCount;
         ret = CMP(ull1, ull2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOOTHER)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.OtherOperationCount;
         ull2 = iocounters2.OtherOperationCount;
         ret = CMP(ull1, ull2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOREADBYTES)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.ReadTransferCount;
         ull2 = iocounters2.ReadTransferCount;
         ret = CMP(ull1, ull2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOWRITEBYTES)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.WriteTransferCount;
         ull2 = iocounters2.WriteTransferCount;
         ret = CMP(ull1, ull2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOOTHERBYTES)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.OtherTransferCount;
         ull2 = iocounters2.OtherTransferCount;
         ret = CMP(ull1, ull2);
index 3f8bcbd..c409f80 100644 (file)
@@ -869,6 +869,7 @@ void TaskManager_OnTabWndSelChange(void)
     HMENU  hViewMenu;
     HMENU  hSubMenu;
     WCHAR  szTemp[256];
+    SYSTEM_INFO sysInfo;
 
     hMenu = GetMenu(hMainWnd);
     hViewMenu = GetSubMenu(hMenu, 2);
@@ -947,16 +948,28 @@ void TaskManager_OnTabWndSelChange(void)
             DeleteMenu(hMenu, 3, MF_BYPOSITION);
             DrawMenuBar(hMainWnd);
         }
-        hSubMenu = CreatePopupMenu();
 
-        LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256);
-        AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp);
+        GetSystemInfo(&sysInfo);
 
-        LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256);
-        AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp);
+        /* Hide CPU graph options on single CPU systems */
+        if (sysInfo.dwNumberOfProcessors > 1)
+        {
+            hSubMenu = CreatePopupMenu();
+
+            LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256);
+            AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp);
+
+            LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256);
+            AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp);
+
+            LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256);
+            AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp);
 
-        LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256);
-        AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp);
+            if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
+                CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
+            else
+                CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
+        }
 
         LoadStringW(hInst, IDS_MENU_SHOWKERNELTIMES, szTemp, 256);
         AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, szTemp);
@@ -965,10 +978,7 @@ void TaskManager_OnTabWndSelChange(void)
             CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
         else
             CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED);
-        if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
-            CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
-        else
-            CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
+
         /*
          * Give the tab control focus
          */
index 2d685ae..7031c76 100644 (file)
@@ -492,7 +492,7 @@ static int comp_FindSubFile(void *p, const void *key,
                             int leaf, void** next)
 {
     *next = (char *)p+strlen(p)+(leaf?5:3);
-    WINE_TRACE("Comparing '%s' with '%s'\n", (char *)p, (char *)key);
+    WINE_TRACE("Comparing '%s' with '%s'\n", (char *)p, (const char *)key);
     return strcmp(p, key);
 }
 
@@ -1601,7 +1601,7 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* page, struct RtfData* rd,
             case 0xEE:
             case 0xEF:
                 {
-                    char*       ptr = (char*) format + 8;
+                    const char*       ptr = (const char*) format + 8;
                     BYTE        type = format[3];
                     int         wnd = -1;
 
index 89ff51c..4f24a71 100644 (file)
@@ -1,3 +1,5 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="winver" type="win32gui" installbase="system32" installname="winver.exe" unicode="yes">
        <include base="winver">.</include>
        <library>shell32</library>
index 04e42f8..95b29e8 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">
 <group>
 <module name="rpcss" type="win32cui" installbase="system32" installname="rpcss.exe" unicode="yes">
        <include base="rpcss">.</include>
index 8ccb81d..1b17bfc 100644 (file)
@@ -1,3 +1,5 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="telnetd" type="win32cui" installbase="system32" installname="telnetd.exe" unicode="no">
        <include base="reactos"></include>
        <include base="telnetd">..</include>
index be34bb7..0008cfb 100644 (file)
@@ -1,11 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="tftpd" type="win32cui" installbase="system32" installname="tftpd.exe" allowwarnings="true" unicode="no">
        <include base="reactos"></include>
        <include base="telnetd">..</include>
-
        <library>ntdll</library>
        <library>advapi32</library>
        <library>ws2_32</library>
        <library>wine</library>
-
        <file>tftpd.cpp</file>
 </module>
index fe835ff..7abbcb1 100644 (file)
@@ -428,7 +428,7 @@ CreateFreeLoaderIniForReactos(PWCHAR IniPath,
     /* ReactOS_KdSerial */
     CreateFreeLoaderEntry(IniCache, IniSection,
         L"ReactOS_KdSerial", L"\"ReactOS (RosDbg)\"",
-        L"ReactOS", ArcPath,
+        L"Windows2003", ArcPath,
         L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
 
     /* ReactOS_LogFile */
index 51fe2e7..0bbde01 100644 (file)
@@ -132,6 +132,7 @@ InfpOpenInfFileW(
        IN PCWSTR FileName,
        IN PCWSTR InfClass,
        IN DWORD InfStyle,
+       IN LCID LocaleId,
        OUT PUINT ErrorLine)
 {
        HINF hInf = NULL;
@@ -143,6 +144,7 @@ InfpOpenInfFileW(
        Status = InfOpenFile(
                &hInf,
                &FileNameU,
+               LocaleId,
                &ErrorLineUL);
        *ErrorLine = (UINT)ErrorLineUL;
        if (!NT_SUCCESS(Status))
@@ -252,6 +254,7 @@ INF_OpenBufferedFileA(
        IN ULONG FileSize,
        IN PCSTR InfClass,
        IN DWORD InfStyle,
+       IN LCID LocaleId,
        OUT PUINT ErrorLine)
 {
 #ifdef __REACTOS__
@@ -263,6 +266,7 @@ INF_OpenBufferedFileA(
                &hInf,
                FileBuffer,
                FileSize,
+               LocaleId,
                &ErrorLineUL);
        *ErrorLine = (UINT)ErrorLineUL;
        if (!NT_SUCCESS(Status))
index 52b002d..864d201 100644 (file)
@@ -110,6 +110,7 @@ InfpOpenInfFileW(
        IN PCWSTR FileName,
        IN PCWSTR InfClass,
        IN DWORD InfStyle,
+       IN LCID LocaleId,
        OUT PUINT ErrorLine);
 
 #endif /* __REACTOS__ */
@@ -132,6 +133,7 @@ INF_OpenBufferedFileA(
        IN ULONG FileSize,
        IN PCSTR InfClass,
        IN DWORD InfStyle,
+       IN LCID LocaleId,
        OUT PUINT ErrorLine);
 
 VOID INF_SetHeap(
index 87df416..7a97b49 100644 (file)
@@ -79,6 +79,8 @@ static PGENERIC_LIST KeyboardList = NULL;
 static PGENERIC_LIST LayoutList = NULL;
 static PGENERIC_LIST LanguageList = NULL;
 
+static LANGID LanguageId = 0;
+
 /* FUNCTIONS ****************************************************************/
 
 static VOID
@@ -422,6 +424,7 @@ CheckUnattendedSetup(VOID)
     UnattendInf = SetupOpenInfFileW(UnattendInfPath,
                                     NULL,
                                     INF_STYLE_WIN4,
+                                    LanguageId,
                                     &ErrorLine);
 
     if (UnattendInf == INVALID_HANDLE_VALUE)
@@ -678,6 +681,8 @@ LanguagePage(PINPUT_RECORD Ir)
         {
             SelectedLanguageId = (PWCHAR)GetListEntryUserData(GetCurrentListEntry(LanguageList));
 
+            LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF);
+
             if (wcscmp(SelectedLanguageId, DefaultLanguage))
             {
                 UpdateKBLayout();
@@ -765,6 +770,7 @@ SetupStartPage(PINPUT_RECORD Ir)
     SetupInf = SetupOpenInfFileW(FileNameBuffer,
                                  NULL,
                                  INF_STYLE_WIN4,
+                                 LanguageId,
                                  &ErrorLine);
 
     if (SetupInf == INVALID_HANDLE_VALUE)
@@ -3045,6 +3051,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
                                           InfFileSize,
                                           (const CHAR*) NULL,
                                           INF_STYLE_WIN4,
+                                          LanguageId,
                                           &ErrorLine);
 
         if (InfHandle == INVALID_HANDLE_VALUE)
@@ -3259,6 +3266,8 @@ RegistryPage(PINPUT_RECORD Ir)
 
         DPRINT("Action: %S  File: %S  Section %S\n", Action, File, Section);
 
+        if (Action == NULL) break; // Hackfix
+
         if (!_wcsicmp (Action, L"AddReg"))
         {
             Delete = FALSE;
@@ -3274,7 +3283,7 @@ RegistryPage(PINPUT_RECORD Ir)
 
         CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE), File);
 
-        if (!ImportRegistryFile(File, Section, Delete))
+        if (!ImportRegistryFile(File, Section, LanguageId, Delete))
         {
             DPRINT("Importing %S failed\n", File);
 
index d313b4d..a808129 100644 (file)
@@ -617,6 +617,7 @@ registry_callback (HINF hInf, PCWSTR Section, BOOLEAN Delete)
 BOOLEAN
 ImportRegistryFile(PWSTR Filename,
                    PWSTR Section,
+                   LCID LocaleId,
                    BOOLEAN Delete)
 {
   WCHAR FileNameBuffer[MAX_PATH];
@@ -632,6 +633,7 @@ ImportRegistryFile(PWSTR Filename,
                        FileNameBuffer,
                        NULL,
                        INF_STYLE_WIN4,
+                       LocaleId,
                        &ErrorLine);
   if (hInf == INVALID_HANDLE_VALUE)
     {
index d764704..63d2b67 100644 (file)
@@ -29,6 +29,7 @@
 BOOLEAN
 ImportRegistryFile(PWSTR Filename,
                   PWSTR Section,
+                  LCID LocaleId,
                   BOOLEAN Delete);
 
 BOOLEAN
index fa96c8c..51f3c03 100644 (file)
@@ -4,10 +4,10 @@
        <bootstrap installbase="$(CDOUTPUT)/system32" nameoncd="smss.exe" />
        <include base="usetup">.</include>
        <include base="zlib">.</include>
-       <include base="inflib">.</include>
+       <include base="newinflib">.</include>
        <include base="ReactOS">include/reactos/drivers</include>
        <library>zlib</library>
-       <library>inflib</library>
+       <library>newinflib</library>
        <library>ext2lib</library>
        <library>vfatlib</library>
        <library>ntdll</library>
index 18541bf..8184af7 100644 (file)
@@ -166,7 +166,7 @@ VOID ConOutChar (TCHAR c)
 VOID ConPuts(LPTSTR szText, DWORD nStdHandle)
 {
        ConWrite(szText, _tcslen(szText), nStdHandle);
-       ConWrite(_T("\n"), 1, nStdHandle);
+       ConWrite(_T("\r\n"), 2, nStdHandle);
 }
 
 VOID ConOutResPaging(BOOL NewPage, UINT resID)
index 4ca8b83..7cb99a7 100644 (file)
@@ -703,7 +703,7 @@ VOID CompleteFilename (LPTSTR strIN, BOOL bNext, LPTSTR strOut, UINT cusor)
                                LastSpace = i;
 
                }
-               /* insert the quoation and move things around */
+               /* insert the quotation and move things around */
                if(szPrefix[LastSpace + 1] != _T('\"') && LastSpace != -1)
                {
                        memmove ( &szPrefix[LastSpace+1], &szPrefix[LastSpace], (_tcslen(szPrefix)-LastSpace+1) * sizeof(TCHAR) );
@@ -712,14 +712,17 @@ VOID CompleteFilename (LPTSTR strIN, BOOL bNext, LPTSTR strOut, UINT cusor)
                        {
                                _tcscat(szPrefix,_T("\""));
                        }
-                               szPrefix[LastSpace + 1] = _T('\"');
+                       szPrefix[LastSpace + 1] = _T('\"');
                }
                else if(LastSpace == -1)
                {
-                       _tcscpy(szBaseWord,_T("\""));
-                       _tcscat(szBaseWord,szPrefix);
-                       _tcscpy(szPrefix,szBaseWord);
-
+                       /* Add quotation only if none exists already */
+                       if (szPrefix[0] != _T('\"'))
+                       {
+                               _tcscpy(szBaseWord,_T("\""));
+                               _tcscat(szBaseWord,szPrefix);
+                               _tcscpy(szPrefix,szBaseWord);
+                       }
                }
        }
 
index 492e388..b0c5059 100644 (file)
Binary files a/base/shell/explorer/res/startmenu.ico and b/base/shell/explorer/res/startmenu.ico differ
index 59f9f30..ba9f42b 100755 (executable)
@@ -363,6 +363,12 @@ _tmain(int argc, TCHAR *argv[])
                PrintWin32Error( szMsg, GetLastError());
                return -1;
        }
+       else if ( driveType == 1 )
+       {
+               LoadString( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
+               PrintWin32Error( szMsg, GetLastError());
+               return -1;
+       }
 
        if( driveType != DRIVE_FIXED ) {
                LoadString( GetModuleHandle(NULL), STRING_INSERT_DISK, (LPTSTR) szMsg,RC_STRING_MAX_SIZE);
index 950580d..9dba766 100644 (file)
@@ -1,3 +1,5 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="runonce" type="win32gui" installbase="system32" installname="runonce.exe" unicode="yes">
        <include base="runonce">.</include>
        <library>advapi32</library>
index 9eb9602..81027d4 100644 (file)
@@ -212,7 +212,6 @@ StartAutoApplications(
         WARN("FindFirstFile(%s) failed with error %lu\n", debugstr_w(szPath), GetLastError());
         return;
     }
-    szPath[len] = L'\0';
 
     do
     {
@@ -220,9 +219,10 @@ StartAutoApplications(
         {
             memset(&ExecInfo, 0x0, sizeof(SHELLEXECUTEINFOW));
             ExecInfo.cbSize = sizeof(ExecInfo);
+            wcscpy(&szPath[len+1], findData.cFileName);
             ExecInfo.lpVerb = L"open";
-            ExecInfo.lpFile = findData.cFileName;
-            ExecInfo.lpDirectory = szPath;
+            ExecInfo.lpFile = szPath;
+            ExecInfo.lpDirectory = NULL;
             TRACE("Executing %s in directory %s\n",
                 debugstr_w(findData.cFileName), debugstr_w(szPath));
             ShellExecuteExW(&ExecInfo);
index 471a7f4..f84fa71 100644 (file)
@@ -1,12 +1,14 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
-<if property="ARCH" value="i386>
+<group xmlns:xi="http://www.w3.org/2001/XInclude">
+<if property="ARCH" value="i386">
        <module name="bootcd" type="iso" output="ReactOS.iso">
                <bootsector>isoboot</bootsector>
        </module>
 </if>
-<ifnot property="ARCH" value="i386>
+<ifnot property="ARCH" value="i386">
        <module name="bootcd" type="iso" output="ReactOS-$(ARCH).iso">
                <bootsector>isoboot</bootsector>
        </module>
 </ifnot>
+</group>
index a39f33f..4651412 100644 (file)
@@ -41,7 +41,7 @@ HKCR,"rtffile\shell\open\command","",0x00020000,"%SystemRoot%\system32\wordpad.e
 HKCR,".386","",0x00000000,"vxdfile"
 HKCR,".vxd","",0x00000000,"vxdfile"
 HKCR,"vxdfile","",0x00000000,"Virtual Device Driver"
-HKCR,"vxdfile","FriendlyTypeName",0x00020000,"@%SystemRoot%\system32\shell32.dll,-156"
+HKCR,"vxdfile","FriendlyTypeName",0x00020000,"@%SystemRoot%\system32\shell32.dll,-157"
 
 ; Animated Cursors
 HKCR,".ani","",0x00000000,"anifile"
index 350fe18..147f80d 100644 (file)
@@ -41,7 +41,7 @@ HKCR,"rtffile\shell\open\command","",0x00020000,"%SystemRoot%\system32\wordpad.e
 HKCR,".386","",0x00000000,"vxdfile"
 HKCR,".vxd","",0x00000000,"vxdfile"
 HKCR,"vxdfile","",0x00000000,"Virtual Device Driver"
-HKCR,"vxdfile","FriendlyTypeName",0x00020000,"@%SystemRoot%\system32\shell32.dll,-156"
+HKCR,"vxdfile","FriendlyTypeName",0x00020000,"@%SystemRoot%\system32\shell32.dll,-157"
 
 ; Animated Cursors
 HKCR,".ani","",0x00000000,"anifile"
index 8d8c489..086ee67 100644 (file)
@@ -1530,7 +1530,8 @@ HKCU,"Control Panel\Accessibility\Keyboard Preference","On",2,"0"
 ; Internet Explorer
 
 HKCU,Software\Wine\MSHTML,"GeckoUrl",,"http://source.winehq.org/winegecko.php"
-HKCU,Software\Wine\MSHTML,"GeckoCabDir",0x00020000,"%SystemRoot%\"
+;HKCU,Software\Wine\MSHTML,"GeckoCabDir",0x00020000,"%SystemRoot%\"
+HKCU,Software\Wine\MSHTML,"GeckoCabDir",,"C:\ReactOS\"
 
 ; Sound Schemes
 HKCU,"AppEvents",,0x00000012
index 9650563..905f5ef 100644 (file)
Binary files a/boot/bootdata/hivedef_i386.inf and b/boot/bootdata/hivedef_i386.inf differ
index e92deca..8a04d12 100644 (file)
@@ -1,12 +1,14 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
-<if property="ARCH" value="i386>
+<group xmlns:xi="http://www.w3.org/2001/XInclude">
+<if property="ARCH" value="i386">
        <module name="livecd" type="liveiso" output="ReactOS-LiveCD.iso">
                <bootsector>isoboot</bootsector>
        </module>
 </if>
-<ifnot property="ARCH" value="i386>
+<ifnot property="ARCH" value="i386">
        <module name="livecd" type="liveiso" output="ReactOS-LiveCD-$(ARCH).iso">
                <bootsector>isoboot</bootsector>
        </module>
 </ifnot>
+</group>
index 895b3fc..d87de7d 100644 (file)
@@ -489,8 +489,6 @@ drivers\base\nmidebug\nmidebug.sys                  2
 
 drivers\battery\battc\battc.sys                     2
 
-drivers\bus\isapnp\isapnp.sys                       2
-
 drivers\bus\acpi\cmbatt\cmbatt.sys                  2
 drivers\bus\acpi\compbatt\compbatt.sys              2
 
@@ -636,6 +634,7 @@ media\nls\c_28603.nls                               1
 media\nls\c_28604.nls                               1
 media\nls\c_28605.nls                               1
 media\nls\c_28606.nls                               1
+media\drivers\etc\hosts                             5
 media\drivers\etc\services                          5
 media\inf\audio.inf                                 6
 media\inf\acpi.inf                                  6
index 7977e44..35f1c76 100644 (file)
@@ -22,6 +22,7 @@ c_1252.nls=,,,,,,,,,,,,2
 cdfs.sys=,,,,,,x,,,,,,4
 cdrom.sys=,,,,,,x,,,,,,4
 class2.sys=,,,,,,x,,,,,,4
+isapnp.sys=,,,,,,,,,,,,4
 kdcom.dll=,,,,,,,,,,,,2
 disk.sys=,,,,,,x,,,,,,4
 floppy.sys=,,,,,,x,,,,,,4
@@ -36,13 +37,16 @@ ramdisk.sys=,,,,,,x,,,,,,4
 ext2.sys=,,,,,,x,,,,,,4
 
 [HardwareIdsDatabase]
-*PNP0C08 = acpi
+;*PNP0A00 = isapnp
 *PNP0A03 = pci
+*PNP0C08 = acpi
+;PCI\CC_0601 = isapnp
 PCI\CC_0604 = pci
 
 [BootBusExtenders.Load]
 acpi = acpi.sys
 pci = pci.sys
+isapnp = isapnp.sys
 
 [Cabinets]
 Cabinet=reactos.cab
@@ -76,7 +80,7 @@ hal.dll=,,,,,,,,,,,,2
 
 [Files.pci_mp]
 ntkrnlmp.exe=,,,,,,,,,,ntoskrnl.exe,,2
-halmp.dll=,,,,,,,,,,hal.dll,,2
+halmps.dll=,,,,,,,,,,hal.dll,,2
 
 [Display]
 ;<id> = <user friendly name>,<spare>,<service key name>,<hight>,<width>,<bpp>
index 0f6c257..9def109 100644 (file)
@@ -21,22 +21,22 @@ RealEntryPoint:
        mov ss, ax
 
        /* checkPoint Charlie - where it all began... */
-       mov si, offset _CheckPoint0
+       mov si, offset CheckPoint0
        call writestr   
-       
+
        /* Setup a real mode stack */
        mov     sp, stack16
 
        /* Zero BootDrive and BootPartition */
        xor eax, eax
-       mov _BootDrive, eax
-       mov _BootPartition, eax
+       mov BootDrive, eax
+       mov BootPartition, eax
 
        /* Store the boot drive */
-       mov _BootDrive, dl
+       mov BootDrive, dl
 
        /* Store the boot partition */
-       mov _BootPartition, dh
+       mov BootPartition, dh
 
        /* Load the GDT */
        lgdt gdtptr
@@ -46,13 +46,13 @@ RealEntryPoint:
        call x86_16_EnableA20
 
        /* checkPoint Charlie - where it all began... */
-       mov si, offset _CheckPoint1
+       mov si, offset CheckPoint1
        call writestr   
        
        call x86_16_BuildPageTables
        
        /* checkPoint Charlie - where it all began... */
-       mov si, offset _CheckPoint2
+       mov si, offset CheckPoint2
        call writestr   
 
        /* Check if CPU supports CPUID */
@@ -89,26 +89,26 @@ RealEntryPoint:
        /* X64 Processor */
        
        /* checkPoint Charlie - where it all began... */
-       mov si, offset _CheckPoint3
+       mov si, offset CheckPoint3
        call writestr   
 
-       jmp _switch64
+       jmp switch64
        
 NO_X64_SUPPORT_DETECTED:
-       mov  si, offset _NotAnX64Processor      // Loading message
+       mov  si, offset NotAnX64Processor       // Loading message
        call writestr
-       jmp _fail
+       jmp fail
 
 NO_CPUID_SUPPORT_DETECTED:
-       mov  si, offset _NoCPUIDSupport // Loading message
-       call writestr
+       mov  si, offset NoCPUIDSupport  // Loading message
+       call writestr
 
-_fail:
-       jmp _fail
+fail:
+       jmp fail
        nop
        nop
 
-_switch64:
+switch64:
        call x86_16_SwitchToLong
 
        .code64
@@ -119,7 +119,7 @@ _switch64:
 
        /* GO! */
        xor rcx, rcx
-       call _BootMain
+       call BootMain
 
        /* Checkpoint */
 //     mov ax, LMODE_DS
@@ -174,14 +174,14 @@ x86_16_BuildPageTables:
        push es
 
        /* Get segment of pml4 */
-       mov eax, offset _pml4_startup
+       mov eax, offset pml4_startup
        shr eax, 4
        mov es, ax
        cld
        xor di, di
 
        /* One entry in the PML4 pointing to PDP */
-       mov eax, offset _pdp_startup
+       mov eax, offset pdp_startup
        or eax, 0x00f
        stosd
        /* clear rest */
@@ -190,7 +190,7 @@ x86_16_BuildPageTables:
        rep stosd
 
        /* One entry in the PDP pointing to PD */
-       mov eax, offset _pd_startup
+       mov eax, offset pd_startup
        or eax, 0x00f
        stosd
        /* clear rest */
@@ -268,7 +268,7 @@ x86_16_SwitchToLong:
        mov eax, 0x00a0                 // Set PAE and PGE: 10100000b
        mov cr4, eax
 
-       mov edx, offset _pml4_startup // Point cr3 at PML4
+       mov edx, offset pml4_startup // Point cr3 at PML4
        mov cr3, edx
 
        mov ecx, 0xC0000080             // Specify EFER MSR
@@ -405,42 +405,42 @@ gdtptr:
        .long   gdt                     /* Base Address */
 
 
-.global _BootDrive
-_BootDrive:
+.global BootDrive
+BootDrive:
     .long 0
     
-.global _BootPartition
-_BootPartition:
+.global BootPartition
+BootPartition:
     .long 0
 
-.global _NotAnX64Processor
-_NotAnX64Processor:
+.global NotAnX64Processor
+NotAnX64Processor:
        .ascii "FreeLoader: No x64-compatible CPU detected! Exiting..."
        .byte 0x0d, 0x0a, 0
 
-.global _NoCPUIDSupport
-_NoCPUIDSupport:
+.global NoCPUIDSupport
+NoCPUIDSupport:
        .ascii "FreeLoader: No CPUID instruction support detected! Exiting..."
        .byte 0x0d, 0x0a, 0
 
 /////////////////////////// Checkpoint messages ///////////////////////////////
-.global _CheckPoint0
-_CheckPoint0:
+.global CheckPoint0
+CheckPoint0:
        .ascii "Starting FreeLoader..."
        .byte 0x0d, 0x0a, 0
        
-.global _CheckPoint1
-_CheckPoint1:
+.global CheckPoint1
+CheckPoint1:
        .ascii "FreeLoader[16-bit]: building page tables..."
        .byte 0x0d, 0x0a, 0
        
-.global _CheckPoint2
-_CheckPoint2:
+.global CheckPoint2
+CheckPoint2:
        .ascii "FreeLoader[16-bit]: checking CPU for x64 long mode..."
        .byte 0x0d, 0x0a, 0
 
-.global _CheckPoint3
-_CheckPoint3:
+.global CheckPoint3
+CheckPoint3:
        .ascii "FreeLoader: Switching to x64 long mode..."
        .byte 0x0d, 0x0a, 0
 
index ce7bb35..eb3ba3c 100644 (file)
 #include <arch.h>
 
 
-EXTERN(_ChainLoadBiosBootSectorCode)
+EXTERN(ChainLoadBiosBootSectorCode)
        .code64
 
        call x86_64_SwitchToReal
        .code16
 
        /* Set the boot drive */
-       mov dl, _BootDrive
+       mov dl, BootDrive
 
        /* Load segment registers */
        cli
@@ -46,7 +46,7 @@ EXTERN(_ChainLoadBiosBootSectorCode)
 //     ljmpl   $0x0000,$0x7C00
        jmp 0x7c00:0x0000
 
-EXTERN(_SoftReboot)
+EXTERN(SoftReboot)
        .code64
 
        call    x86_64_SwitchToReal
index d6b081c..6871fe0 100644 (file)
@@ -24,7 +24,7 @@
 #include <arch.h>
 
 
-EXTERN(_DriveMapInt13HandlerStart)
+EXTERN(DriveMapInt13HandlerStart)
 Int13Handler:
 
        pushw   %bp
@@ -82,7 +82,7 @@ CallOldInt13Handler:
 
        /* Call old int 13h handler with new drive number */
        .byte   0x9a /* lcall */
-EXTERN(_DriveMapOldInt13HandlerAddress)
+EXTERN(DriveMapOldInt13HandlerAddress)
        .word   0
        .word   0
 
@@ -105,7 +105,7 @@ CallersFlags:
 PassedInDriveNumber:
        .byte   0
 
-EXTERN(_DriveMapInt13HandlerMapList)
+EXTERN(DriveMapInt13HandlerMapList)
 Int13HandlerMapCount:
        .byte   0
 
@@ -129,4 +129,4 @@ Int13HandlerDrive4:
 Int13HandlerDriveNew4:
        .byte   0
 
-EXTERN(_DriveMapInt13HandlerEnd)
+EXTERN(DriveMapInt13HandlerEnd)
index 6dfb91d..ee3ee6f 100644 (file)
@@ -33,7 +33,7 @@
  *    0x00000400: Found 80486 CPU without CPUID support
  */
 
-EXTERN(_CpuidSupported)
+EXTERN(CpuidSupported)
        .code32
 
        pushl   %ecx                    /* save ECX */
@@ -80,7 +80,7 @@ NoCpuid:
  * VOID GetCpuid(U32 Level, U32 *eax, U32 *ebx, U32 *ecx, U32 *edx);
  */
 
-EXTERN(_GetCpuid)
+EXTERN(GetCpuid)
        .code32
 
        pushl   %ebp
@@ -123,7 +123,7 @@ EXTERN(_GetCpuid)
  * U64 RDTSC(VOID);
  */
 
-EXTERN(_RDTSC)
+EXTERN(RDTSC)
        .code32
        rdtsc
        ret
index ff0ae71..1958927 100644 (file)
@@ -35,7 +35,7 @@ _pnp_bios_entry_point:
 _pnp_bios_data_segment:
        .word   0
 
-EXTERN(_PnpBiosSupported)
+EXTERN(PnpBiosSupported)
        .code64
 
        push rdi
@@ -113,7 +113,7 @@ _pnp_node_size:
 _pnp_node_count:
        .word   0
 
-EXTERN(_PnpBiosGetDeviceNodeCount)
+EXTERN(PnpBiosGetDeviceNodeCount)
        .code64
 
        push rbp
@@ -182,7 +182,7 @@ _pnp_buffer_offset:
 _pnp_node_number:
        .byte   0
 
-EXTERN(_PnpBiosGetDeviceNode)
+EXTERN(PnpBiosGetDeviceNode)
        .code64
 
        push rbp
index 833fcc3..195bf09 100644 (file)
@@ -273,7 +273,7 @@ i386CommonExceptionHandler:
        SAVE_CPU_REGS
 
        pushl   $SCREEN_ATTR
-       call    _MachVideoClearScreen
+       call    MachVideoClearScreen
        add     $4,%esp
 
        movl    $i386ExceptionHandlerText,%esi
@@ -485,7 +485,7 @@ i386PrintChar:
        pushl   $SCREEN_ATTR
        andl    $0xff,%eax
        pushl   %eax
-       call    _MachVideoPutChar
+       call    MachVideoPutChar
        addl    $16,%esp
 
        ret
index 1c1f2db..a22e409 100644 (file)
@@ -63,7 +63,7 @@ Int386_regsout:
 /*
  * int Int386(int ivec, REGS* in, REGS* out);
  */
-EXTERN(_Int386)
+EXTERN(Int386)
        .code64
 
        /* Get the function parameters */
index 9ca6f85..cad77bf 100644 (file)
@@ -39,33 +39,6 @@ EnableA20()
     /* Already done */
 }
 
-void
-DumpLoaderBlock()
-{
-       DbgPrint("LoaderBlock @ %p.\n", &LoaderBlock);
-       DbgPrint("Flags = 0x%x.\n", LoaderBlock.Flags);
-       DbgPrint("MemLower = 0x%p.\n", (PVOID)LoaderBlock.MemLower);
-       DbgPrint("MemHigher = 0x%p.\n", (PVOID)LoaderBlock.MemHigher);
-       DbgPrint("BootDevice = 0x%x.\n", LoaderBlock.BootDevice);
-       DbgPrint("CommandLine = %s.\n", LoaderBlock.CommandLine);
-       DbgPrint("ModsCount = 0x%x.\n", LoaderBlock.ModsCount);
-       DbgPrint("ModsAddr = 0x%p.\n", LoaderBlock.ModsAddr);
-       DbgPrint("Syms = 0x%s.\n", LoaderBlock.Syms);
-       DbgPrint("MmapLength = 0x%x.\n", LoaderBlock.MmapLength);
-       DbgPrint("MmapAddr = 0x%p.\n", (PVOID)LoaderBlock.MmapAddr);
-       DbgPrint("RdLength = 0x%x.\n", LoaderBlock.RdLength);
-       DbgPrint("RdAddr = 0x%p.\n", (PVOID)LoaderBlock.RdAddr);
-       DbgPrint("DrivesCount = 0x%x.\n", LoaderBlock.DrivesCount);
-       DbgPrint("DrivesAddr = 0x%p.\n", (PVOID)LoaderBlock.DrivesAddr);
-       DbgPrint("ConfigTable = 0x%x.\n", LoaderBlock.ConfigTable);
-       DbgPrint("BootLoaderName = 0x%x.\n", LoaderBlock.BootLoaderName);
-       DbgPrint("PageDirectoryStart = 0x%p.\n", (PVOID)LoaderBlock.PageDirectoryStart);
-       DbgPrint("PageDirectoryEnd = 0x%p.\n", (PVOID)LoaderBlock.PageDirectoryEnd);
-       DbgPrint("KernelBase = 0x%p.\n", (PVOID)LoaderBlock.KernelBase);
-       DbgPrint("ArchExtra = 0x%p.\n", (PVOID)LoaderBlock.ArchExtra);
-
-}
-
 /*++
  * FrLdrStartup
  * INTERNAL
@@ -86,222 +59,7 @@ VOID
 NTAPI
 FrLdrStartup(ULONG Magic)
 {
-       /* Disable Interrupts */
-       _disable();
-
-       /* Re-initalize EFLAGS */
-       __writeeflags(0);
-
-       /* Initialize the page directory */
-       FrLdrSetupPageDirectory();
-
-       /* Set the new PML4 */
-       __writecr3((ULONGLONG)pPML4);
-
-       FrLdrSetupGdtIdt();
-
-       LoaderBlock.FrLdrDbgPrint = DbgPrint;
-
-//     DumpLoaderBlock();
-
-       DbgPrint("Jumping to kernel @ %p.\n", KernelEntryPoint);
-
-       /* Jump to Kernel */
-       (*KernelEntryPoint)(Magic, &LoaderBlock);
-
-}
-
-PPAGE_DIRECTORY_AMD64
-FrLdrGetOrCreatePageDir(PPAGE_DIRECTORY_AMD64 pDir, ULONG Index)
-{
-       PPAGE_DIRECTORY_AMD64 pSubDir;
-
-       if (!pDir)
-               return NULL;
-
-       if (!pDir->Pde[Index].Valid)
-       {
-               pSubDir = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
-               if (!pSubDir)
-                       return NULL;
-               RtlZeroMemory(pSubDir, PAGE_SIZE);
-               pDir->Pde[Index].PageFrameNumber = PtrToPfn(pSubDir);
-               pDir->Pde[Index].Valid = 1;
-               pDir->Pde[Index].Write = 1;
-       }
-       else
-       {
-               pSubDir = (PPAGE_DIRECTORY_AMD64)((ULONGLONG)(pDir->Pde[Index].PageFrameNumber) * PAGE_SIZE);
-       }
-       return pSubDir;
-}
-
-BOOLEAN
-FrLdrMapSinglePage(ULONGLONG VirtualAddress, ULONGLONG PhysicalAddress)
-{
-       PPAGE_DIRECTORY_AMD64 pDir3, pDir2, pDir1;
-       ULONG Index;
-
-       pDir3 = FrLdrGetOrCreatePageDir(pPML4, VAtoPXI(VirtualAddress));
-       pDir2 = FrLdrGetOrCreatePageDir(pDir3, VAtoPPI(VirtualAddress));
-       pDir1 = FrLdrGetOrCreatePageDir(pDir2, VAtoPDI(VirtualAddress));
-
-       if (!pDir1)
-               return FALSE;
-
-       Index = VAtoPTI(VirtualAddress);
-       if (pDir1->Pde[Index].Valid)
-       {
-               return FALSE;
-       }
-
-       pDir1->Pde[Index].Valid = 1;
-       pDir1->Pde[Index].Write = 1;
-       pDir1->Pde[Index].PageFrameNumber = PhysicalAddress / PAGE_SIZE;
-
-       return TRUE;
-}
-
-ULONG
-FrLdrMapRangeOfPages(ULONGLONG VirtualAddress, ULONGLONG PhysicalAddress, ULONG cPages)
-{
-       ULONG i;
-
-       for (i = 0; i < cPages; i++)
-       {
-               if (!FrLdrMapSinglePage(VirtualAddress, PhysicalAddress))
-               {
-                       return i;
-               }
-               VirtualAddress += PAGE_SIZE;
-               PhysicalAddress += PAGE_SIZE;
-       }
-       return i;
+       DbgPrint("ReactOS loader is unsupported! Halting.\n", KernelEntryPoint);
+    for(;;);
 }
 
-
-/*++
- * FrLdrSetupPageDirectory
- * INTERNAL
- *
- *     Sets up the ReactOS Startup Page Directory.
- *
- * Params:
- *     None.
- *
- * Returns:
- *     None.
- *--*/
-VOID
-FASTCALL
-FrLdrSetupPageDirectory(VOID)
-{
-       ULONG KernelPages;
-       PVOID UserSharedData;
-
-       /* Allocate a Page for the PML4 */
-       pPML4 = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
-
-       ASSERT(pPML4);
-
-       /* The page tables are located at 0xfffff68000000000 
-        * We create a recursive self mapping through all 4 levels at 
-        * virtual address 0xfffff6fb7dbedf68 */
-       pPML4->Pde[VAtoPXI(PXE_BASE)].Valid = 1;
-       pPML4->Pde[VAtoPXI(PXE_BASE)].Write = 1;
-       pPML4->Pde[VAtoPXI(PXE_BASE)].PageFrameNumber = PtrToPfn(pPML4);
-
-       /* Setup low memory pages */
-       if (FrLdrMapRangeOfPages(0, 0, 1024) < 1024)
-       {
-               DbgPrint("Could not map low memory pages.\n");
-       }
-
-       /* Setup kernel pages */
-       KernelPages = (ROUND_TO_PAGES(NextModuleBase - KERNEL_BASE_PHYS) / PAGE_SIZE);
-       if (FrLdrMapRangeOfPages(KernelBase, KERNEL_BASE_PHYS, KernelPages) != KernelPages)
-       {
-               DbgPrint("Could not map %d kernel pages.\n", KernelPages);
-       }
-
-       /* Setup a page for the idt */
-       pIdt = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
-       IdtBase = KernelBase + KernelPages * PAGE_SIZE;
-       if (!FrLdrMapSinglePage(IdtBase, (ULONGLONG)pIdt))
-       {
-               DbgPrint("Could not map idt page.\n", KernelPages);
-       }
-
-       /* Setup a page for the gdt & tss */
-       pGdt = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
-       GdtBase = IdtBase + PAGE_SIZE;
-       TssBase = GdtBase + 20 * sizeof(ULONG64); // FIXME: don't hardcode
-       if (!FrLdrMapSinglePage(GdtBase, (ULONGLONG)pGdt))
-       {
-               DbgPrint("Could not map gdt page.\n", KernelPages);
-       }
-
-       /* Setup KUSER_SHARED_DATA page */
-       UserSharedData = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
-       if (!FrLdrMapSinglePage(KI_USER_SHARED_DATA, (ULONG64)UserSharedData))
-       {
-               DbgPrint("Could not map KUSER_SHARED_DATA page.\n", KernelPages);
-       }
-
-       /* Map APIC page */
-       if (!FrLdrMapSinglePage(APIC_BASE, APIC_PHYS_BASE))
-       {
-               DbgPrint("Could not map APIC page.\n");
-       }
-
-}
-
-VOID
-FrLdrSetupGdtIdt()
-{
-       PKGDTENTRY64 Entry;
-       KDESCRIPTOR Desc;
-
-       RtlZeroMemory(pGdt, PAGE_SIZE);
-
-       /* Setup KGDT_64_R0_CODE */
-       Entry = KiGetGdtEntry(pGdt, KGDT_64_R0_CODE);
-       *(PULONG64)Entry = 0x00209b0000000000ULL;
-
-       /* Setup KGDT_64_R0_SS */
-       Entry = KiGetGdtEntry(pGdt, KGDT_64_R0_SS);
-       *(PULONG64)Entry = 0x00cf93000000ffffULL;
-
-       /* Setup KGDT_64_DATA */
-       Entry = KiGetGdtEntry(pGdt, KGDT_64_DATA);
-       *(PULONG64)Entry = 0x00cff3000000ffffULL;
-
-       /* Setup KGDT_64_R3_CODE */
-       Entry = KiGetGdtEntry(pGdt, KGDT_64_R3_CODE);
-       *(PULONG64)Entry = 0x0020fb0000000000ULL;
-
-       /* Setup KGDT_32_R3_TEB */
-       Entry = KiGetGdtEntry(pGdt, KGDT_32_R3_TEB);
-       *(PULONG64)Entry = 0xff40f3fd50003c00ULL;
-
-       /* Setup TSS entry */
-       Entry = KiGetGdtEntry(pGdt, KGDT_TSS);
-       KiInitGdtEntry(Entry, TssBase, sizeof(KTSS), I386_TSS, 0);
-
-       /* Setup the gdt descriptor */
-       Desc.Limit = 12 * sizeof(ULONG64) - 1;
-       Desc.Base = (PVOID)GdtBase;
-
-       /* Set the new Gdt */
-       __lgdt(&Desc.Limit);
-       DbgPrint("Gdtr.Base = %p\n", Desc.Base);
-
-       /* Setup the idt descriptor */
-       Desc.Limit = 12 * sizeof(ULONG64) - 1;
-       Desc.Base = (PVOID)IdtBase;
-
-       /* Set the new Idt */
-       __lidt(&Desc.Limit);
-       DbgPrint("Idtr.Base = %p\n", Desc.Base);
-
-}
index 368338e..2d515e9 100644 (file)
         * This boots the kernel
         */
        .code64
-    .globl _PageDirectoryStart
+    .globl PageDirectoryStart
     
-    .globl _pml4_startup
-    .globl _pdp_startup
-    .globl _pd_startup
+    .globl pml4_startup
+    .globl pdp_startup
+    .globl pd_startup
 
-    .globl _PageDirectoryEnd
+    .globl PageDirectoryEnd
 
        //
        // Boot information structure
        //
 
-EXTERN(_reactos_memory_map_descriptor_size)
+EXTERN(reactos_memory_map_descriptor_size)
        .long   0
 
-EXTERN(_reactos_memory_map)
+EXTERN(reactos_memory_map)
        .rept   (32 * /*sizeof(memory_map_t)*/24)
        .byte   0
        .endr
 
 .bss
-_PageDirectoryStart:
-_pml4_startup:
+PageDirectoryStart:
+pml4_startup:
        .fill 4096, 1, 0
 
-_pdp_startup:
+pdp_startup:
        .fill 4096, 1, 0
 
-_pd_startup:
+pd_startup:
        .fill 4096, 1, 0
 
-_PageDirectoryEnd:
+PageDirectoryEnd:
index d4654cc..97577aa 100644 (file)
@@ -452,7 +452,23 @@ static LONG DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
         SectorCount = Geometry.Sectors;
     }
     else
-        return EINVAL;
+    {
+        DPRINTM(DPRINT_HWDETECT, "Using legacy sector size detection\n");
+
+        /* Fall back to legacy detection */
+        if (DrivePartition == 0xff)
+        {
+            /* This is a CD-ROM device */
+            SectorSize = 2048;
+        }
+        else
+        {
+            /* This is either a floppy disk device (DrivePartition == 0) or
+             * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
+             * it doesn't matter which one because they both have 512 bytes per sector */
+            SectorSize = 512;
+        }
+    }
 
     if (DrivePartition != 0xff && DrivePartition != 0)
     {
@@ -1419,10 +1435,10 @@ DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
       /* Set Interrupt */
       PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
       PartialDescriptor->Type = CmResourceTypeInterrupt;
-      PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+      PartialDescriptor->ShareDisposition = CmResourceShareShared;
       PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
       PartialDescriptor->u.Interrupt.Level = Irq[i];
-      PartialDescriptor->u.Interrupt.Vector = 0;
+      PartialDescriptor->u.Interrupt.Vector = Irq[i];
       PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
 
       /* Set serial data (device specific) */
@@ -1529,7 +1545,7 @@ DetectParallelPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
          PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
          PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
          PartialDescriptor->u.Interrupt.Level = Irq[i];
-         PartialDescriptor->u.Interrupt.Vector = 0;
+         PartialDescriptor->u.Interrupt.Vector = Irq[i];
          PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
        }
 
@@ -1715,7 +1731,7 @@ DetectKeyboardController(PCONFIGURATION_COMPONENT_DATA BusKey)
   PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
   PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
   PartialDescriptor->u.Interrupt.Level = 1;
-  PartialDescriptor->u.Interrupt.Vector = 0;
+  PartialDescriptor->u.Interrupt.Vector = 1;
   PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
 
   /* Set IO Port 0x60 */
@@ -1887,7 +1903,7 @@ DetectPS2Mouse(PCONFIGURATION_COMPONENT_DATA BusKey)
       PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined;
       PartialResourceList.PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
       PartialResourceList.PartialDescriptors[0].u.Interrupt.Level = 12;
-      PartialResourceList.PartialDescriptors[0].u.Interrupt.Vector = 0;
+      PartialResourceList.PartialDescriptors[0].u.Interrupt.Vector = 12;
       PartialResourceList.PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF;
 
       /* Create controller key */
index 74f3e22..1b985f2 100644 (file)
@@ -45,7 +45,6 @@ PcMachInit(const char *CmdLine)
     MachVtbl.PrepareForReactOS = PcPrepareForReactOS;
     MachVtbl.GetMemoryMap = PcMemGetMemoryMap;
     MachVtbl.DiskGetBootPath = DiskGetBootPath;
-    MachVtbl.DiskNormalizeSystemPath = DiskNormalizeSystemPath;
     MachVtbl.DiskReadLogicalSectors = PcDiskReadLogicalSectors;
     MachVtbl.DiskGetDriveGeometry = PcDiskGetDriveGeometry;
     MachVtbl.DiskGetCacheableBlockCount = PcDiskGetCacheableBlockCount;
index 442c7be..704a7ae 100644 (file)
@@ -48,7 +48,6 @@ XboxMachInit(const char *CmdLine)
   MachVtbl.PrepareForReactOS = XboxPrepareForReactOS;
   MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
   MachVtbl.DiskGetBootPath = DiskGetBootPath;
-  MachVtbl.DiskNormalizeSystemPath = DiskNormalizeSystemPath;
   MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors;
   MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry;
   MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount;
index e0aa98c..1f30141 100644 (file)
@@ -44,12 +44,6 @@ VOID LoadAndBootBootSector(PCSTR OperatingSystemName)
                return;
        }
 
-       if (!MachDiskNormalizeSystemPath(FileName, sizeof(FileName)))
-       {
-               UiMessageBox("Invalid path to boot sector file");
-               return;
-       }
-
        FilePointer = FsOpenFile(FileName);
        if (!FilePointer)
        {
index 5c7680b..ff325b3 100644 (file)
@@ -138,7 +138,20 @@ static LONG DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
 
     if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition))
         return EINVAL;
-    SectorSize = (DrivePartition == 0xff ? 2048 : 512);
+
+    if (DrivePartition == 0xff)
+    {
+        /* This is a CD-ROM device */
+        SectorSize = 2048;
+    }
+    else
+    {
+        /* This is either a floppy disk device (DrivePartition == 0) or
+         * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
+         * it doesn't matter which one because they both have 512 bytes per sector */
+         SectorSize = 512;
+    }
+
     if (DrivePartition != 0xff && DrivePartition != 0)
     {
         if (!XboxDiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
index 57cacd2..9abd56b 100644 (file)
@@ -440,7 +440,6 @@ void PpcDefaultMachVtbl()
 
     MachVtbl.GetMemoryMap = PpcGetMemoryMap;
 
-    MachVtbl.DiskNormalizeSystemPath = DiskNormalizeSystemPath;
     MachVtbl.DiskGetBootPath = PpcDiskGetBootPath;
     MachVtbl.DiskReadLogicalSectors = PpcDiskReadLogicalSectors;
     MachVtbl.DiskGetDriveGeometry = PpcDiskGetDriveGeometry;
index 16ee1be..b7ce329 100644 (file)
@@ -107,62 +107,80 @@ DiskGetBootPath(char *BootPath, unsigned Size)
 {
        static char Path[] = "multi(0)disk(0)";
        char Device[4];
-    
-       _itoa(BootDrive, Device, 10);
-       if (Size <= sizeof(Path) + 6 + strlen(Device))
-       {
-               return FALSE;
-       }
-       strcpy(BootPath, Path);
-       strcat(BootPath, BootDrive < 0x80 ? "fdisk" : "cdrom");
-       strcat(strcat(strcat(BootPath, "("), Device), ")");
-    
-       if (strcmp(BootPath, "multi(0)disk(0)cdrom(128)") == 0)
-               strcpy(BootPath, "multi(0)disk(0)rdisk(0)partition(1)");
-       return TRUE;
-}
+       char Partition[4];
+       PARTITION_TABLE_ENTRY PartitionEntry;
+       MASTER_BOOT_RECORD MasterBootRecord;
 
-BOOLEAN
-DiskNormalizeSystemPath(char *SystemPath, unsigned Size)
-{
-       CHAR BootPath[256];
-       ULONG PartitionNumber;
-       ULONG DriveNumber;
-       PARTITION_TABLE_ENTRY PartEntry;
-       char *p;
-    
-       if (!DissectArcPath(SystemPath, BootPath, &DriveNumber, &PartitionNumber))
+       if (BootDrive < 0x80)
        {
-               return FALSE;
+               /* This is a floppy */
+
+               if (Size <= sizeof(Path) + 7 + strlen(Device))
+               {
+                       return FALSE;
+               }
+
+               strcpy(BootPath, Path);
+
+               strcat(BootPath, "fdisk");
+
+               _itoa(BootDrive, Device, 10);
+               strcat(BootPath, "(");
+               strcat(BootPath, Device);
+               strcat(BootPath, ")");
        }
-    
-       if (0 != PartitionNumber)
+       /* FIXME */
+       else if (DiskReadBootRecord(BootDrive, 0, &MasterBootRecord))
        {
-               return TRUE;
-       }
-    
-       if (! DiskGetActivePartitionEntry(DriveNumber,
-                                         &PartEntry,
-                                         &PartitionNumber) ||
-           PartitionNumber < 1 || 9 < PartitionNumber)
+               /* This is a hard disk */
+
+               if (!DiskGetActivePartitionEntry(BootDrive, &PartitionEntry, &BootPartition))
+               {
+                       DbgPrint("Invalid active partition information\n");
+                       return FALSE;
+               }
+
+               if (Size <= sizeof(Path) + 18 + strlen(Device) + strlen(Partition))
+               {
+                       return FALSE;
+               }
+
+               strcpy(BootPath, Path);
+
+               strcat(BootPath, "rdisk");
+
+               _itoa(BootDrive - 0x80, Device, 10);
+               strcat(BootPath, "(");
+               strcat(BootPath, Device);
+               strcat(BootPath, ")");
+
+               _itoa(BootPartition, Partition, 10);
+               strcat(BootPath, "partition(");
+               strcat(BootPath, Partition);
+               strcat(BootPath, ")");
+        }
+       else
        {
-               return FALSE;
-       }
-    
-       p = SystemPath;
-       while ('\0' != *p && 0 != _strnicmp(p, "partition(", 10)) {
-               p++;
-       }
-       p = strchr(p, ')');
-       if (NULL == p || '0' != *(p - 1)) {
-               return FALSE;
+               /* This is a CD-ROM drive */
+
+               if (Size <= sizeof(Path) + 7 + strlen(Device))
+               {
+                       return FALSE;
+               }
+
+               strcpy(BootPath, Path);
+
+               strcat(BootPath, "cdrom");
+
+               _itoa(BootDrive - 0x80, Device, 10);
+               strcat(BootPath, "(");
+               strcat(BootPath, Device);
+               strcat(BootPath, ")");
        }
-       *(p - 1) = '0' + PartitionNumber;
-    
+
        return TRUE;
 }
 
-
 // This function is in arch/i386/i386disk.c
 //VOID DiskStopFloppyMotor(VOID)
 
index 8966e67..b93b2e1 100644 (file)
@@ -197,7 +197,6 @@ BOOLEAN DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord,
 
 BOOLEAN DiskReadBootRecord(ULONG DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord)
 {
-       char            ErrMsg[64];
        ULONG           Index;
 
        // Read master boot record
@@ -231,9 +230,6 @@ BOOLEAN DiskReadBootRecord(ULONG DriveNumber, ULONGLONG LogicalSectorNumber, PMA
        // Check the partition table magic value
        if (BootRecord->MasterBootRecordMagic != 0xaa55)
        {
-               sprintf(ErrMsg, "Invalid partition table magic 0x%x found on drive 0x%lx",
-                       BootRecord->MasterBootRecordMagic, DriveNumber);
-               DiskError(ErrMsg, 0);
                return FALSE;
        }
 
index 2b8a8b2..6aa231c 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<!DOCTYPE directory SYSTEM "../../../tools/rbuild/project.dtd">
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="freeldr_arch" type="objectlibrary" crt="static">
        <include base="freeldr_base">include</include>
        <include base="freeldr_base">cache</include>
index c8c2ab1..a8b784b 100644 (file)
@@ -23,7 +23,9 @@
                <file>disk.c</file>
                <file>partition.c</file>
                <file>ramdisk.c</file>
-               <file>scsiport.c</file>
+               <if property="ARCH" value="i386">
+                       <file>scsiport.c</file>
+               </if>
        </directory>
        <directory name="fs">
                <file>ext2.c</file>
index af46178..9068e00 100644 (file)
@@ -45,7 +45,7 @@
 
 #define HYPERSPACE_BASE             0xfffff70000000000ULL
 #define HAL_BASE                    0xffffffff80000000ULL
-#define APIC_BASE                   0xfffffffffee00000ULL // FIXME
+#define APIC_BASE                   0xFFFFFFFFFFFE0000ULL
 
 #define APIC_PHYS_BASE              0xfee00000
 
index daaaa49..191ee12 100644 (file)
@@ -127,7 +127,6 @@ extern ULONG BootDrive;
 extern ULONG BootPartition;
 
 BOOLEAN DiskGetBootPath(char *BootPath, unsigned Size);
-BOOLEAN DiskNormalizeSystemPath(char *SystemPath, unsigned Size);
 
 
 ///////////////////////////////////////////////////////////////////////////////////////
index 0c0076f..6595205 100644 (file)
@@ -62,7 +62,6 @@ typedef struct tagMACHVTBL
   ULONG (*GetMemoryMap)(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize);
 
   BOOLEAN (*DiskGetBootPath)(char *BootPath, unsigned Size);
-  BOOLEAN (*DiskNormalizeSystemPath)(char *SystemPath, unsigned Size);
   BOOLEAN (*DiskReadLogicalSectors)(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer);
   BOOLEAN (*DiskGetDriveGeometry)(ULONG DriveNumber, PGEOMETRY DriveGeometry);
   ULONG (*DiskGetCacheableBlockCount)(ULONG DriveNumber);
index 10c2017..5aea40c 100644 (file)
@@ -97,13 +97,6 @@ VOID LoadAndBootLinux(PCSTR OperatingSystemName, PCSTR Description)
                goto LinuxBootFailed;
        }
 
-       // Open the boot volume
-       if (!MachDiskNormalizeSystemPath(LinuxBootPath, sizeof(LinuxBootPath)))
-       {
-               UiMessageBox("Invalid boot path");
-               goto LinuxBootFailed;
-       }
-
        // Open the kernel
        LinuxKernel = FsOpenFile(LinuxKernelName);
        if (!LinuxKernel)
index 9021a7c..c898bf4 100644 (file)
@@ -37,7 +37,6 @@
 #undef MachBeep
 #undef MachPrepareForReactOS
 #undef MachDiskGetBootPath
-#undef MachDiskNormalizeSystemPath
 #undef MachDiskReadLogicalSectors
 #undef MachDiskGetDriveGeometry
 #undef MachDiskGetCacheableBlockCount
@@ -152,12 +151,6 @@ MachDiskGetBootPath(char *BootPath, unsigned Size)
   return MachVtbl.DiskGetBootPath(BootPath, Size);
 }
 
-BOOLEAN
-MachDiskNormalizeSystemPath(char *SystemPath, unsigned Size)
-{
-  return MachVtbl.DiskNormalizeSystemPath(SystemPath, Size);
-}
-
 BOOLEAN
 MachDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 {
index 3ca69fa..4b7f97a 100644 (file)
@@ -60,7 +60,7 @@ BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, ULONG* BootDrive, ULONG* B
                if (p == NULL)
                        return FALSE;
                p++;
-               *BootPartition = 0xff;
+               *BootPartition = 0;
        }
        else if (_strnicmp(p, "cdrom(", 6) == 0)
        {
@@ -69,7 +69,7 @@ BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, ULONG* BootDrive, ULONG* B
                 *  multi(0)disk(0)cdrom(x)\path
                 */
                p = p + 6;
-               *BootDrive = atoi(p);
+               *BootDrive = atoi(p) + 0x80;
                p = strchr(p, ')');
                if (p == NULL)
                        return FALSE;
index 12c8c66..81b654b 100644 (file)
@@ -718,12 +718,6 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
     }
     else
     {
-        if (! MachDiskNormalizeSystemPath(SystemPath,
-                                          sizeof(SystemPath)))
-        {
-            UiMessageBox("Invalid system path");
-            return;
-        }
         /* copy system path into kernel command line */
         strcpy(reactos_kernel_cmdline, SystemPath);
     }
index 3e3288a..5f979c4 100644 (file)
@@ -252,28 +252,36 @@ WinLdrSetupGdt(PVOID GdtBase, ULONG64 TssBase)
        PKGDTENTRY64 Entry;
        KDESCRIPTOR GdtDesc;
 
-       /* Setup KGDT_64_R0_CODE */
-       Entry = KiGetGdtEntry(GdtBase, KGDT_64_R0_CODE);
+       /* Setup KGDT64_NULL */
+       Entry = KiGetGdtEntry(GdtBase, KGDT64_NULL);
+       *(PULONG64)Entry = 0x0000000000000000ULL;
+
+       /* Setup KGDT64_R0_CODE */
+       Entry = KiGetGdtEntry(GdtBase, KGDT64_R0_CODE);
        *(PULONG64)Entry = 0x00209b0000000000ULL;
 
-       /* Setup KGDT_64_R0_SS */
-       Entry = KiGetGdtEntry(GdtBase, KGDT_64_R0_SS);
+       /* Setup KGDT64_R0_DATA */
+       Entry = KiGetGdtEntry(GdtBase, KGDT64_R0_DATA);
        *(PULONG64)Entry = 0x00cf93000000ffffULL;
 
-       /* Setup KGDT_64_DATA */
-       Entry = KiGetGdtEntry(GdtBase, KGDT_64_DATA);
+       /* Setup KGDT64_R3_CMCODE */
+       Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_CMCODE);
+       *(PULONG64)Entry = 0x00cffb000000ffffULL;
+
+       /* Setup KGDT64_R3_DATA */
+       Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_DATA);
        *(PULONG64)Entry = 0x00cff3000000ffffULL;
 
-       /* Setup KGDT_64_R3_CODE */
-       Entry = KiGetGdtEntry(GdtBase, KGDT_64_R3_CODE);
+       /* Setup KGDT64_R3_CODE */
+       Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_CODE);
        *(PULONG64)Entry = 0x0020fb0000000000ULL;
 
-       /* Setup KGDT_32_R3_TEB */
-       Entry = KiGetGdtEntry(GdtBase, KGDT_32_R3_TEB);
+       /* Setup KGDT64_R3_CMTEB */
+       Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_CMTEB);
        *(PULONG64)Entry = 0xff40f3fd50003c00ULL;
 
        /* Setup TSS entry */
-       Entry = KiGetGdtEntry(GdtBase, KGDT_TSS);
+       Entry = KiGetGdtEntry(GdtBase, KGDT64_SYS_TSS);
        KiInitGdtEntry(Entry, TssBase, sizeof(KTSS), I386_TSS, 0);
 
     /* Setup GDT descriptor */
@@ -333,15 +341,8 @@ WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG64 Pcr, IN ULONG64 Tss)
     /* LDT is unused */
 //    __lldt(0);
 
-    /* Load selectors for DS/ES/FS/GS/SS */
-    Ke386SetDs(KGDT_64_DATA | RPL_MASK);   // 0x2b
-    Ke386SetEs(KGDT_64_DATA | RPL_MASK);   // 0x2b
-    Ke386SetFs(KGDT_32_R3_TEB | RPL_MASK); // 0x53
-       Ke386SetGs(KGDT_64_DATA | RPL_MASK);   // 0x2b
-       Ke386SetSs(KGDT_64_R0_SS);             // 0x18
-
        /* Load TSR */
-       __ltr(KGDT_TSS);
+       __ltr(KGDT64_SYS_TSS);
 
     DPRINTM(DPRINT_WINDOWS, "leave WinLdrSetProcessorContext\n");
 }
index 9a09169..c3c21d4 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Display Control Panel
  * FILE:            lib/cpl/desk/appearance.c
@@ -486,11 +485,17 @@ AppearancePage_OnDestroy(HWND hwndDlg, GLOBALS *g)
        return TRUE;
 }
 
+static void
+UpdateSelectedThemeId(HWND hwndDlg, GLOBALS *g)
+{
+       int sel;
+       sel = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETCURSEL, 0, 0);
+       g->Theme.Id = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETITEMDATA, (WPARAM)sel, 0);
+}
 
 INT_PTR CALLBACK
 AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-       INT i;
        GLOBALS *g;
        LPNMHDR lpnm;
 
@@ -538,8 +543,7 @@ AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
                                        {
                                                PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                                                g->Theme.bHasChanged = TRUE;
-                                               i = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETCURSEL, 0, 0);
-                                               g->Theme.Id = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETITEMDATA, (WPARAM)i, 0);
+                                               UpdateSelectedThemeId(hwndDlg, g);
                                                LoadThemeFromReg(g);
                                                //SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, WM_PAINT, 0, 0);
                                        }
@@ -557,6 +561,7 @@ AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
                                case PSN_APPLY:
                                        if (g->Theme.bHasChanged)
                                        {
+                                               UpdateSelectedThemeId(hwndDlg, g);
                                                ApplyTheme(g);
                                        }
                                        return TRUE;
index fe4362a..c03c66d 100644 (file)
@@ -94,14 +94,17 @@ AddListViewItems(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
 
     ZeroMemory(&listItem, sizeof(LV_ITEM));
     listItem.mask       = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
-    listItem.state      = LVIS_SELECTED;
+    listItem.state      = 0;
     listItem.pszText    = backgroundItem->szDisplayName;
     listItem.iImage     = -1;
     listItem.iItem      = pGlobalData->listViewItemCount;
     listItem.lParam     = pGlobalData->listViewItemCount;
 
     (void)ListView_InsertItem(hwndBackgroundList, &listItem);
-    ListView_SetItemState(hwndBackgroundList, pGlobalData->listViewItemCount, LVIS_SELECTED, LVIS_SELECTED);
+    ListView_SetItemState(hwndBackgroundList, 
+                          pGlobalData->listViewItemCount,
+                          LVIS_SELECTED,
+                          LVIS_SELECTED);
 
     pGlobalData->listViewItemCount++;
 
@@ -143,14 +146,17 @@ AddListViewItems(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
 
             ZeroMemory(&listItem, sizeof(LV_ITEM));
             listItem.mask       = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
-            listItem.state      = LVIS_SELECTED;
+            listItem.state      = 0;
             listItem.pszText    = backgroundItem->szDisplayName;
             listItem.iImage     = sfi.iIcon;
             listItem.iItem      = pGlobalData->listViewItemCount;
             listItem.lParam     = pGlobalData->listViewItemCount;
 
             (void)ListView_InsertItem(hwndBackgroundList, &listItem);
-            ListView_SetItemState(hwndBackgroundList, pGlobalData->listViewItemCount, LVIS_SELECTED, LVIS_SELECTED);
+            ListView_SetItemState(hwndBackgroundList,
+                                  pGlobalData->listViewItemCount,
+                                  LVIS_SELECTED,
+                                  LVIS_SELECTED);
 
             pGlobalData->listViewItemCount++;
         }
@@ -454,13 +460,17 @@ OnBrowseButton(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
 
         ZeroMemory(&listItem, sizeof(LV_ITEM));
         listItem.mask       = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
-        listItem.state      = LVIS_SELECTED;
+        listItem.state      = 0;
         listItem.pszText    = backgroundItem->szDisplayName;
         listItem.iImage     = sfi.iIcon;
         listItem.iItem      = pGlobalData->listViewItemCount;
         listItem.lParam     = pGlobalData->listViewItemCount;
 
         (void)ListView_InsertItem(hwndBackgroundList, &listItem);
+        ListView_SetItemState(hwndBackgroundList,
+                              pGlobalData->listViewItemCount,
+                              LVIS_SELECTED,
+                              LVIS_SELECTED);
         SendMessage(hwndBackgroundList, WM_VSCROLL, SB_BOTTOM, 0);
 
         pGlobalData->listViewItemCount++;
index 6fd0ac7..3a7c8b4 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: effappdlg.c 24836 2007-02-12 03:12:56Z tkreuzer $
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Display Control Panel
  * FILE:            dll/cpl/desk/effappdlg.c
index 408f651..651a167 100644 (file)
@@ -58,7 +58,6 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x1
 BEGIN
     GROUPBOX        "²íôîðìàö³ÿ ïðî âåðñ³þ",IDC_STATIC,6,3,210,73
     CONTROL         "Ïîçíà÷èòè ÿê ðîáî÷ó ñòàíö³þ",IDC_REPORTASWORKSTATION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,57,88,10
-    CONTROL         "Ïîçíà÷èòè ÿê ðîáî÷ó ñòàíö³þ",IDC_REPORTASWORKSTATION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,57,88,10
     LTEXT           "ReactOS áóäóºòüñÿ ÿê ñåðâåðíà ÎÑ. Îáðàòè ïðàïîðåöü, ùîá çì³íèòè ëèøå öåé äîäàòîê.",IDC_STATIC,15,15,183,41
     PUSHBUTTON      "OK",IDOK,166,83,50,14
 END
index 4420b76..2571abb 100644 (file)
@@ -336,6 +336,7 @@ CBDAPinControl_fnConstructor(
             if (SUCCEEDED(hr))
             {
                 // register device filter
+                OutputDebugStringW(L"CBDAPinControl_fnConstructor registering device filter with network provider\n");
                 hr = pNetworkProvider->RegisterDeviceFilter(pUnknown, &RegistrationCtx);
                 if (SUCCEEDED(hr))
                 {
@@ -361,7 +362,6 @@ CBDAPinControl_fnConstructor(
                     WCHAR Buffer[100];
                     swprintf(Buffer, L"CBDAPinControl_fnConstructor failed to register filter with %lx\n", hr);
                     OutputDebugStringW(Buffer);
-                    DebugBreak();
                 }
             }
         }
index e7c4b1f..8229bd2 100644 (file)
@@ -357,6 +357,7 @@ CKsAllocator::GetBuffer(
 
         if (!m_FreeList.empty())
         {
+            OutputDebugStringW(L"CKsAllocator::GetBuffer HACK\n");
             Sample = m_FreeList.top();
             m_FreeList.pop();
         }
index a6c3bdf..da07796 100644 (file)
@@ -71,7 +71,6 @@ CEnumPins::QueryInterface(
     OutputDebugStringW(Buffer);
     CoTaskMemFree(lpstr);
 
-DebugBreak();
     return E_NOINTERFACE;
 }
 
index 51b7872..e56eacb 100644 (file)
@@ -700,7 +700,6 @@ CInputPin::Receive(IMediaSample *pSample)
 {
 #ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::Receive NotImplemented\n");
-    DebugBreak();
 #endif
 
     return E_NOTIMPL;
@@ -712,7 +711,6 @@ CInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSample
 {
 #ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::ReceiveMultiple NotImplemented\n");
-    DebugBreak();
 #endif
 
     return E_NOTIMPL;
@@ -724,7 +722,6 @@ CInputPin::ReceiveCanBlock( void)
 {
 #ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::ReceiveCanBlock NotImplemented\n");
-    DebugBreak();
 #endif
 
     return S_FALSE;
@@ -923,7 +920,6 @@ CInputPin::KsQualityNotify(
     OutputDebugStringW(L"CInputPin::KsQualityNotify NotImplemented\n");
 #endif
 
-    DebugBreak();
     return E_NOTIMPL;
 }
 
@@ -1114,7 +1110,6 @@ CInputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
 {
 #ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::Connect NotImplemented\n");
-    DebugBreak();
 #endif
     return NOERROR;
 }
@@ -1199,7 +1194,6 @@ CInputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
 
 #ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CInputPin::ConnectionMediaType NotImplemented\n");
-    DebugBreak();
 #endif
 
     return E_NOTIMPL;
@@ -1496,7 +1490,6 @@ CInputPin::CreatePin(
         WCHAR Buffer[100];
         swprintf(Buffer, L"CInputPin::CreatePin unexpected communication %u %s\n", m_Communication, m_PinName);
         OutputDebugStringW(Buffer);
-        DebugBreak();
 #endif
         hr = E_FAIL;
     }
@@ -1629,7 +1622,6 @@ CInputPin::CreatePinHandle(
         {
 #ifdef KSPROXY_TRACE
             OutputDebugStringW(L"CInputPin::CreatePinHandle GetSupportedSets failed\n");
-            DebugBreak();
 #endif
             return hr;
         }
@@ -1640,7 +1632,6 @@ CInputPin::CreatePinHandle(
         {
 #ifdef KSPROXY_TRACE
             OutputDebugStringW(L"CInputPin::CreatePinHandle LoadProxyPlugins failed\n");
-            DebugBreak();
 #endif
             return hr;
         }
@@ -1783,7 +1774,6 @@ CInputPin::LoadProxyPlugins(
         {
             // store plugin
             m_Plugins.push_back(pUnknown);
-DebugBreak();
         }
         // close key
         RegCloseKey(hSubKey);
index e041193..28270cd 100644 (file)
@@ -21,7 +21,6 @@ public:
     STDMETHODIMP_(ULONG) Release()
     {
         InterlockedDecrement(&m_Ref);
-        DebugBreak();
         if (!m_Ref)
         {
             if (m_Allocator)
@@ -280,7 +279,6 @@ STDMETHODCALLTYPE
 CMediaSample::SetMediaType(AM_MEDIA_TYPE *pMediaType)
 {
     OutputDebugStringW(L"CMediaSample::SetMediaType NotImplemented\n");
-    DebugBreak();
     return E_NOTIMPL;
 }
 
index 17f0780..2bf85c8 100644 (file)
@@ -246,8 +246,16 @@ COutputPin::COutputPin(
 
     ZeroMemory(m_FramingProp, sizeof(m_FramingProp));
     ZeroMemory(m_FramingEx, sizeof(m_FramingEx));
+    ZeroMemory(&m_MediaFormat, sizeof(AM_MEDIA_TYPE));
 
     hr = KsGetMediaType(0, &m_MediaFormat, KsObjectParent->KsGetObjectHandle(), m_PinId);
+
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[100];
+    swprintf(Buffer, L"COutputPin::COutputPin Format %p pbFormat %lu\n", &m_MediaFormat, m_MediaFormat.cbFormat);
+    OutputDebugStringW(Buffer);
+#endif
+
     assert(hr == S_OK);
 
     InitializeCriticalSection(&m_Lock);
@@ -1518,6 +1526,8 @@ COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
     HRESULT hr;
     ALLOCATOR_PROPERTIES Properties;
     IMemAllocatorCallbackTemp *pMemCallback;
+    LPGUID pGuid;
+    ULONG NumGuids = 0;
 
 #ifdef KSPROXY_TRACE
     WCHAR Buffer[200];
@@ -1540,6 +1550,20 @@ COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
          pmt = &m_MediaFormat;
     }
 
+    if (m_hPin == INVALID_HANDLE_VALUE)
+    {
+        hr = CreatePin(pmt);
+        if (FAILED(hr))
+        {
+#ifdef KSPROXY_TRACE
+            swprintf(Buffer, L"COutputPin::Connect CreatePin handle failed with %lx\n", hr);
+            OutputDebugStringW(Buffer);
+#endif
+            return hr;
+        }
+    }
+
+
     // query for IMemInput interface
     hr = pReceivePin->QueryInterface(IID_IMemInputPin, (void**)&m_MemInputPin);
     if (FAILED(hr))
@@ -1548,7 +1572,6 @@ COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
         OutputDebugStringW(L"COutputPin::Connect no IMemInputPin interface\n");
 #endif
 
-        DebugBreak();
         return hr;
     }
 
@@ -1649,10 +1672,24 @@ COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
         return hr;
     }
 
-    if (!m_hPin)
+
+    assert(m_hPin != INVALID_HANDLE_VALUE);
+
+    // get all supported sets
+    if (m_Plugins.size() == 0)
     {
-        //FIXME create pin handle
-        assert(0);
+        if (GetSupportedSets(&pGuid, &NumGuids))
+        {
+            // load all proxy plugins
+            if (FAILED(LoadProxyPlugins(pGuid, NumGuids)));
+            {
+#ifdef KSPROXY_TRACE
+                OutputDebugStringW(L"COutputPin::Connect LoadProxyPlugins failed\n");
+#endif
+            }
+            // free sets
+            CoTaskMemFree(pGuid);
+        }
     }
 
     // receive connection;
@@ -1946,13 +1983,26 @@ COutputPin::CreatePin(
     // query for pin medium
     hr = KsQueryMediums(&MediumList);
     if (FAILED(hr))
+    {
+#ifdef KSPROXY_TRACE
+        WCHAR Buffer[100];
+        swprintf(Buffer, L"COutputPin::CreatePin KsQueryMediums failed %lx\n", hr);
+        OutputDebugStringW(Buffer);
+#endif
         return hr;
+    }
 
     // query for pin interface
     hr = KsQueryInterfaces(&InterfaceList);
     if (FAILED(hr))
     {
         // failed
+#ifdef KSPROXY_TRACE
+        WCHAR Buffer[100];
+        swprintf(Buffer, L"COutputPin::CreatePin KsQueryInterfaces failed %lx\n", hr);
+        OutputDebugStringW(Buffer);
+#endif
+
         CoTaskMemFree(MediumList);
         return hr;
     }
@@ -2003,6 +2053,12 @@ COutputPin::CreatePin(
                 CoTaskMemFree(MediumList);
                 CoTaskMemFree(InterfaceList);
 
+#ifdef KSPROXY_TRACE
+                WCHAR Buffer[100];
+                swprintf(Buffer, L"COutputPin::CreatePin failed to create interface handler %lx\n", hr);
+                OutputDebugStringW(Buffer);
+#endif
+
                 return hr;
             }
 
@@ -2010,7 +2066,12 @@ COutputPin::CreatePin(
             hr = InterfaceHandler->KsSetPin((IKsPin*)this);
             if (FAILED(hr))
             {
-                // failed to load interface handler plugin
+                // failed to initialize interface handler plugin
+#ifdef KSPROXY_TRACE
+                WCHAR Buffer[100];
+                swprintf(Buffer, L"COutputPin::CreatePin failed to initialize interface handler %lx\n", hr);
+                OutputDebugStringW(Buffer);
+#endif
                 InterfaceHandler->Release();
                 CoTaskMemFree(MediumList);
                 CoTaskMemFree(InterfaceList);
@@ -2027,7 +2088,6 @@ COutputPin::CreatePin(
         WCHAR Buffer[100];
         swprintf(Buffer, L"COutputPin::CreatePin unexpected communication %u %s\n", m_Communication, m_PinName);
         OutputDebugStringW(Buffer);
-        DebugBreak();
 #endif
 
         hr = E_FAIL;
@@ -2037,6 +2097,12 @@ COutputPin::CreatePin(
     CoTaskMemFree(MediumList);
     CoTaskMemFree(InterfaceList);
 
+#ifdef KSPROXY_TRACE
+    WCHAR Buffer[100];
+    swprintf(Buffer, L"COutputPin::CreatePin Result %lx\n", hr);
+    OutputDebugStringW(Buffer);
+#endif
+
     return hr;
 }
 
@@ -2058,11 +2124,14 @@ COutputPin::CreatePinHandle(
     //KSPROPERTY Property;
     //ULONG BytesReturned;
 
+    OutputDebugStringW(L"COutputPin::CreatePinHandle\n");
+
     if (m_hPin != INVALID_HANDLE_VALUE)
     {
         // pin already exists
         //CloseHandle(m_hPin);
         //m_hPin = INVALID_HANDLE_VALUE;
+        OutputDebugStringW(L"COutputPin::CreatePinHandle pin already exists\n");
         return S_OK;
     }
 
@@ -2075,9 +2144,10 @@ COutputPin::CreatePinHandle(
     if (!PinConnect)
     {
         // failed
+        OutputDebugStringW(L"COutputPin::CreatePinHandle out of memory\n");
         return E_OUTOFMEMORY;
     }
-
+        OutputDebugStringW(L"COutputPin::CreatePinHandle copy pinconnect\n");
     // setup request
     CopyMemory(&PinConnect->Interface, Interface, sizeof(KSPIN_INTERFACE));
     CopyMemory(&PinConnect->Medium, Medium, sizeof(KSPIN_MEDIUM));
@@ -2088,7 +2158,7 @@ COutputPin::CreatePinHandle(
 
     // get dataformat offset
     DataFormat = (PKSDATAFORMAT)(PinConnect + 1);
-
+        OutputDebugStringW(L"COutputPin::CreatePinHandle copy format\n");
     // copy data format
     DataFormat->FormatSize = sizeof(KSDATAFORMAT) + pmt->cbFormat;
     DataFormat->Flags = 0;
@@ -2101,13 +2171,19 @@ COutputPin::CreatePinHandle(
     if (pmt->cbFormat)
     {
         // copy extended format
+        WCHAR Buffer[100];
+        swprintf(Buffer, L"COutputPin::CreatePinHandle copy format %p pbFormat %lu\n", pmt, pmt->cbFormat);
+        OutputDebugStringW(Buffer);
         CopyMemory((DataFormat + 1), pmt->pbFormat, pmt->cbFormat);
     }
 
     // get IKsObject interface
     hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
     if (FAILED(hr))
+    {
+        OutputDebugStringW(L"COutputPin::CreatePinHandle no IID_IKsObject interface\n");
         return hr;
+    }
 
     // get parent filter handle
     hFilter = KsObjectParent->KsGetObjectHandle();
@@ -2116,13 +2192,19 @@ COutputPin::CreatePinHandle(
     KsObjectParent->Release();
 
     if (!hFilter)
+    {
+        OutputDebugStringW(L"COutputPin::CreatePinHandle no filter handle\n");
         return E_HANDLE;
+    }
 
+    OutputDebugStringW(L"COutputPin::CreatePinHandle before creating pin\n");
     // create pin
-    hr = KsCreatePin(hFilter, PinConnect, GENERIC_READ, &m_hPin);
+    DWORD dwError = KsCreatePin(hFilter, PinConnect, GENERIC_READ, &m_hPin);
 
-    if (SUCCEEDED(hr))
+    if (dwError == ERROR_SUCCESS)
     {
+        OutputDebugStringW(L"COutputPin::CreatePinHandle created pin\n");
+
         // store current interface / medium
         CopyMemory(&m_Medium, Medium, sizeof(KSPIN_MEDIUM));
         CopyMemory(&m_Interface, Interface, sizeof(KSPIN_INTERFACE));
@@ -2173,42 +2255,14 @@ COutputPin::CreatePinHandle(
         if (FAILED(InitializeIOThread()))
         {
             OutputDebugStringW(L"COutputPin::CreatePinHandle failed to initialize i/o thread\n");
-            DebugBreak();
-        }
-
-        LPGUID pGuid;
-        ULONG NumGuids = 0;
-
-        // get all supported sets
-        hr = GetSupportedSets(&pGuid, &NumGuids);
-        if (FAILED(hr))
-        {
-#ifdef KSPROXY_TRACE
-            OutputDebugStringW(L"CInputPin::CreatePinHandle GetSupportedSets failed\n");
-            DebugBreak();
-#endif
-            return hr;
         }
 
-        // load all proxy plugins
-        hr = LoadProxyPlugins(pGuid, NumGuids);
-        if (FAILED(hr))
-        {
-#ifdef KSPROXY_TRACE
-            OutputDebugStringW(L"CInputPin::CreatePinHandle LoadProxyPlugins failed\n");
-            DebugBreak();
-#endif
-            return hr;
-        }
-
-        // free sets
-        CoTaskMemFree(pGuid);
-
-
         //TODO
         // connect pin pipes
 
     }
+    else
+        OutputDebugStringW(L"COutputPin::CreatePinHandle failed to create pin\n");
     // free pin connect
      CoTaskMemFree(PinConnect);
 
@@ -2338,7 +2392,6 @@ COutputPin::LoadProxyPlugins(
         {
             // store plugin
             m_Plugins.push_back(pUnknown);
-DebugBreak();
         }
         // close key
         RegCloseKey(hSubKey);
@@ -2357,17 +2410,48 @@ COutputPin::IoProcessRoutine()
     IMediaSample *Sample;
     LONG SampleCount;
     HRESULT hr;
-    PKSSTREAM_SEGMENT StreamSegment;
+    PKSSTREAM_SEGMENT StreamSegment;
     HANDLE hEvent;
-    IMediaSample * Samples[1];
+    IMediaSample ** Samples;
+    LONG NumHandles;
+    DWORD dwStatus;
 
 #ifdef KSPROXY_TRACE
     WCHAR Buffer[200];
 #endif
 
+    NumHandles = m_Properties.cBuffers / 2;
+
+    if (!NumHandles)
+        NumHandles = 8;
+
+    assert(NumHandles);
+
+    //allocate stream segment array
+    StreamSegment = (PKSSTREAM_SEGMENT*)CoTaskMemAlloc(sizeof(PKSSTREAM_SEGMENT) * NumHandles);
+    if (!StreamSegment)
+    {
+        OutputDebugStringW(L"COutputPin::IoProcessRoutine out of memory\n");
+        return E_FAIL;
+    }
+
+    // allocate handle array
+    Samples = (IMediaSample**)CoTaskMemAlloc(sizeof(IMediaSample*) * NumHandles);
+    if (!Samples)
+    {
+        OutputDebugStringW(L"COutputPin::IoProcessRoutine out of memory\n");
+        return E_FAIL;
+    }
+
+    // zero handles array
+    ZeroMemory(StreamSegment, sizeof(PKSSTREAM_SEGMENT) * NumHandles);
+    ZeroMemory(Samples, sizeof(IMediaSample*) * NumHandles);
+
     // first wait for the start event to signal
     WaitForSingleObject(m_hStartEvent, INFINITE);
 
+    m_IoCount = 0;
+
     assert(m_InterfaceHandler);
     do
     {
@@ -2392,14 +2476,14 @@ COutputPin::IoProcessRoutine()
 
         // fill buffer
         SampleCount = 1;
-        Samples[0] = Sample;
+        Samples[m_IoCount] = Sample;
 
         Sample->SetTime(NULL, NULL);
         hr = m_InterfaceHandler->KsProcessMediaSamples(NULL, /* FIXME */
-                                                       Samples,
+                                                       &Samples[m_IoCount],
                                                        &SampleCount,
                                                        KsIoOperation_Read,
-                                                       &StreamSegment);
+                                                       &StreamSegment[m_IoCount]);
         if (FAILED(hr) || !StreamSegment)
         {
 #ifdef KSPROXY_TRACE
@@ -2409,14 +2493,26 @@ COutputPin::IoProcessRoutine()
             break;
         }
 
-        // get completion event
-        hEvent = StreamSegment->CompletionEvent;
+        // interface handle should increment pending i/o count
+        assert(m_IoCount >= 1);
+
+        swprintf(Buffer, L"COutputPin::IoProcessRoutine m_IoCount %lu NumHandles %lu\n", m_IoCount, NumHandles);
+        OutputDebugStringW(Buffer);
+
+        if (m_IoCount != NumHandles)
+            continue;
+
+        // get completion handle
+        hEvent = StreamSegment[0]->CompletionEvent;
 
         // wait for i/o completion
-        WaitForSingleObject(hEvent, INFINITE);
+        dwStatus = WaitForSingleObject(hEvent, INFINITE);
+
+        swprintf(Buffer, L"COutputPin::IoProcessRoutine dwStatus %lx Error %lx NumHandles %lu\n", dwStatus, GetLastError(), NumHandles);
+        OutputDebugStringW(Buffer);
 
         // perform completion
-        m_InterfaceHandler->KsCompleteIo(StreamSegment);
+        m_InterfaceHandler->KsCompleteIo(StreamSegment[0]);
 
         // close completion event
         CloseHandle(hEvent);
@@ -2426,7 +2522,7 @@ COutputPin::IoProcessRoutine()
             assert(m_MemInputPin);
 
             // now deliver the sample
-            hr = m_MemInputPin->Receive(Sample);
+            hr = m_MemInputPin->Receive(Samples[0]);
 
 #ifdef KSPROXY_TRACE
             swprintf(Buffer, L"COutputPin::IoProcessRoutine PinName %s IMemInputPin::Receive hr %lx Sample %p m_MemAllocator %p\n", m_PinName, hr, Sample, m_MemAllocator);
@@ -2438,6 +2534,11 @@ COutputPin::IoProcessRoutine()
 
             Sample = NULL;
         }
+
+        //circular stream segment array
+        RtlMoveMemory(StreamSegment, &StreamSegment[1], sizeof(PKSSTREAM_SEGMENT) * (NumHandles - 1));
+        RtlMoveMemory(Samples, &Samples[1], sizeof(IMediaSample*) * (NumHandles - 1));
+
     }while(TRUE);
 
     // signal end of i/o thread
index eae5de0..f7268b1 100644 (file)
@@ -3,7 +3,7 @@
 #define _FORCENAMELESSUNION
 #define BUILDING_KS
 #define _KSDDK_
-//#define KSPROXY_TRACE
+#define KSPROXY_TRACE
 #include <dshow.h>
 //#include <streams.h>
 #include <ks.h>
index bd34ec8..175eff2 100644 (file)
@@ -1954,7 +1954,6 @@ CKsProxy::IsDirty()
 {
 #ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::IsDirty Notimplemented\n");
-    DebugBreak();
 #endif
     return E_NOTIMPL;
 }
@@ -2035,7 +2034,6 @@ CKsProxy::Load(
 
     }while(Length > 0);
 
-    DebugBreak();
     return S_OK;
 }
 
@@ -2059,7 +2057,6 @@ CKsProxy::GetSizeMax(
 {
 #ifdef KSPROXY_TRACE
     OutputDebugStringW(L"CKsProxy::GetSizeMax Notimplemented\n");
-    DebugBreak();
 #endif
 
     return E_NOTIMPL;
@@ -2480,23 +2477,50 @@ CKsProxy::CreatePins()
         // query current instance count
         hr = GetPinInstanceCount(Index, &Instances);
         if (FAILED(hr))
+        {
+#ifdef KSPROXY_TRACE
+            WCHAR Buffer[100];
+            swprintf(Buffer, L"CKsProxy::CreatePins GetPinInstanceCount failed with %lx\n", hr);
+            OutputDebugStringW(Buffer);
+#endif
             continue;
+        }
+
 
         // query pin communication;
         hr = GetPinCommunication(Index, &Communication);
         if (FAILED(hr))
+        {
+#ifdef KSPROXY_TRACE
+            WCHAR Buffer[100];
+            swprintf(Buffer, L"CKsProxy::CreatePins GetPinCommunication failed with %lx\n", hr);
+            OutputDebugStringW(Buffer);
+#endif
             continue;
+        }
 
         if (Instances.CurrentCount == Instances.PossibleCount)
         {
             // already maximum reached for this pin
+#ifdef KSPROXY_TRACE
+            WCHAR Buffer[100];
+            swprintf(Buffer, L"CKsProxy::CreatePins Instances.CurrentCount == Instances.PossibleCount\n");
+            OutputDebugStringW(Buffer);
+#endif
             continue;
         }
 
         // get direction of pin
         hr = GetPinDataflow(Index, &DataFlow);
         if (FAILED(hr))
+        {
+#ifdef KSPROXY_TRACE
+            WCHAR Buffer[100];
+            swprintf(Buffer, L"CKsProxy::CreatePins GetPinDataflow failed with %lx\n", hr);
+            OutputDebugStringW(Buffer);
+#endif
             continue;
+        }
 
         if (DataFlow == KSPIN_DATAFLOW_IN)
             hr = GetPinName(Index, DataFlow, InputPin, &PinName);
@@ -2504,7 +2528,14 @@ CKsProxy::CreatePins()
             hr = GetPinName(Index, DataFlow, OutputPin, &PinName);
 
         if (FAILED(hr))
+        {
+#ifdef KSPROXY_TRACE
+            WCHAR Buffer[100];
+            swprintf(Buffer, L"CKsProxy::CreatePins GetPinName failed with %lx\n", hr);
+            OutputDebugStringW(Buffer);
+#endif
             continue;
+        }
 
         // construct the pins
         if (DataFlow == KSPIN_DATAFLOW_IN)
@@ -2512,6 +2543,11 @@ CKsProxy::CreatePins()
             hr = CInputPin_Constructor((IBaseFilter*)this, PinName, m_hDevice, Index, Communication, IID_IPin, (void**)&pPin);
             if (FAILED(hr))
             {
+#ifdef KSPROXY_TRACE
+                WCHAR Buffer[100];
+                swprintf(Buffer, L"CKsProxy::CreatePins CInputPin_Constructor failed with %lx\n", hr);
+                OutputDebugStringW(Buffer);
+#endif
                 CoTaskMemFree(PinName);
                 continue;
             }
@@ -2522,6 +2558,11 @@ CKsProxy::CreatePins()
             hr = COutputPin_Constructor((IBaseFilter*)this, PinName, Index, Communication, IID_IPin, (void**)&pPin);
             if (FAILED(hr))
             {
+#ifdef KSPROXY_TRACE
+                WCHAR Buffer[100];
+                swprintf(Buffer, L"CKsProxy::CreatePins COutputPin_Constructor failed with %lx\n", hr);
+                OutputDebugStringW(Buffer);
+#endif
                 CoTaskMemFree(PinName);
                 continue;
             }
@@ -2627,9 +2668,12 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog)
     hr = LoadProxyPlugins(pGuid, NumGuids);
     if (FAILED(hr))
     {
+#if 0 //HACK
         CloseHandle(m_hDevice);
         m_hDevice = NULL;
         return hr;
+#endif
+        OutputDebugStringW(L"CKsProxy::LoadProxyPlugins failed!\n");
     }
 
     // free sets
@@ -2638,6 +2682,14 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog)
     // now create the input / output pins
     hr = CreatePins();
 
+#ifdef KSPROXY_TRACE
+    swprintf(Buffer, L"CKsProxy::Load CreatePins %lx\n", hr);
+    OutputDebugStringW(Buffer);
+#endif
+
+    //HACK
+    hr = S_OK;
+
     return hr;
 }
 
@@ -2986,10 +3038,6 @@ STDMETHODCALLTYPE
 CKsProxy::EnumPins(
     IEnumPins **ppEnum)
 {
-#ifdef KSPROXY_TRACE
-    OutputDebugStringW(L"CKsProxy::EnumPins\n");
-#endif
-
     return CEnumPins_fnConstructor(m_Pins, IID_IEnumPins, (void**)ppEnum);
 }
 
index 5677059..9466aaa 100644 (file)
@@ -155,14 +155,6 @@ CEnumPins_fnConstructor(
 {
     CEnumPins * handler = new CEnumPins(NumPins, pins);
 
-#ifdef MSDVBNP_TRACE
-    WCHAR Buffer[MAX_PATH];
-    LPOLESTR lpstr;
-    StringFromCLSID(riid, &lpstr);
-    swprintf(Buffer, L"CEnumPins_fnConstructor riid %s pUnknown %p\n", lpstr, pUnknown);
-    OutputDebugStringW(Buffer);
-#endif
-
     if (!handler)
         return E_OUTOFMEMORY;
 
index b67f232..9c1d309 100644 (file)
@@ -9,10 +9,14 @@
 
 #include "precomp.h"
 
+#ifndef _MSC_VER
+const GUID KSCATEGORY_BDA_NETWORK_PROVIDER = {0x71985f4b, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
+#endif
+
 static INTERFACE_TABLE InterfaceTable[] =
 {
-    {&CLSID_DVBTNetworkProvider, CNetworkProvider_fnConstructor},
-    {NULL, NULL}
+    {&CLSID_DVBTNetworkProvider, CNetworkProvider_fnConstructor, L"ReactOS DVBT Network Provider"},
+    {NULL, NULL, NULL}
 };
 
 extern "C"
@@ -53,8 +57,19 @@ DllUnregisterServer(void)
     HRESULT hr = S_OK;
     HKEY hClass;
 
+
+    hr = StringFromCLSID(KSCATEGORY_BDA_NETWORK_PROVIDER, &pStr);
+    if (FAILED(hr))
+        return hr;
+
     if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_SET_VALUE, &hClass) != ERROR_SUCCESS)
+    {
+        CoTaskMemFree(pStr);
         return E_FAIL;
+    }
+
+    RegDeleteKeyW(hClass, pStr);
+    CoTaskMemFree(pStr);
 
     do
     {
@@ -71,6 +86,24 @@ DllUnregisterServer(void)
     return hr;
 }
 
+VOID
+RegisterBDAComponent(
+    HKEY hFilter,
+    LPCWSTR ComponentClsid,
+    LPCWSTR ComponentName)
+{
+    HKEY hComp;
+
+    // create network provider filter key
+    if (RegCreateKeyExW(hFilter, ComponentClsid, 0, NULL, 0, KEY_WRITE, NULL, &hComp, NULL) == ERROR_SUCCESS)
+    {
+        // store class id
+        RegSetValueExW(hComp, L"CLSID", 0, REG_SZ, (const BYTE*)ComponentClsid, (wcslen(ComponentClsid)+1) * sizeof(WCHAR));
+        RegSetValueExW(hComp, L"FriendlyName", 0, REG_SZ, (const BYTE*)ComponentName, (wcslen(ComponentName)+1) * sizeof(WCHAR));
+        RegCloseKey(hComp);
+    }
+}
+
 extern "C"
 KSDDKAPI
 HRESULT
@@ -80,12 +113,50 @@ DllRegisterServer(void)
     ULONG Index = 0;
     LPOLESTR pStr;
     HRESULT hr = S_OK;
-    HKEY hClass, hKey, hSubKey;
+    HKEY hClass, hKey, hSubKey, hProvider, hInstance, hFilter;
     static LPCWSTR ModuleName = L"msdvbnp.ax";
     static LPCWSTR ThreadingModel = L"Both";
 
+    hr = StringFromCLSID(KSCATEGORY_BDA_NETWORK_PROVIDER, &pStr);
+    if (FAILED(hr))
+        return hr;
+
     if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_WRITE, &hClass) != ERROR_SUCCESS)
+    {
+        CoTaskMemFree(pStr);
+        return E_FAIL;
+    }
+
+    if (RegCreateKeyExW(hClass, pStr, 0, NULL, 0, KEY_WRITE, NULL, &hProvider, NULL) != ERROR_SUCCESS)
+    {
+        RegCloseKey(hClass);
+        CoTaskMemFree(pStr);
+        return E_FAIL;
+    }
+
+    CoTaskMemFree(pStr);
+
+    if (RegCreateKeyExW(hProvider, L"Instance", 0, NULL, 0, KEY_WRITE, NULL, &hInstance, NULL) != ERROR_SUCCESS)
+    {
+        RegCloseKey(hClass);
+        return E_FAIL;
+    }
+    RegCloseKey(hProvider);
+
+    /* open active movie filter category key */
+    if (RegCreateKeyExW(hClass, L"{da4e3da0-d07d-11d0-bd50-00a0c911ce86}\\Instance", 0, NULL, 0, KEY_WRITE, NULL, &hFilter, NULL) != ERROR_SUCCESS)
+    {
+        RegCloseKey(hClass);
+        RegCloseKey(hInstance);
         return E_FAIL;
+    }
+
+    RegisterBDAComponent(hFilter, L"{71985F4A-1CA1-11d3-9CC8-00C04F7971E0}", L"BDA Playback Filter");
+    RegisterBDAComponent(hFilter, L"{71985F4B-1CA1-11D3-9CC8-00C04F7971E0}", L"BDA Network Providers");
+    RegisterBDAComponent(hFilter, L"{71985F48-1CA1-11d3-9CC8-00C04F7971E0}", L"BDA Source Filter");
+    RegisterBDAComponent(hFilter, L"{A2E3074F-6C3D-11D3-B653-00C04F79498E}", L"BDA Transport Information Renderers");
+    RegisterBDAComponent(hFilter, L"{FD0A5AF4-B41D-11d2-9C95-00C04F7971E0}", L"BDA Receiver Component");
+    RegCloseKey(hKey);
 
     do
     {
@@ -104,11 +175,23 @@ DllRegisterServer(void)
             RegCloseKey(hKey);
         }
 
+        if (RegCreateKeyExW(hInstance, InterfaceTable[Index].ProviderName, 0, 0, 0, KEY_WRITE, NULL, &hKey, 0) == ERROR_SUCCESS)
+        {
+            //FIXME filterdata
+            RegSetValueExW(hKey, L"FriendlyName", 0, REG_SZ, (const BYTE*)InterfaceTable[Index].ProviderName, (wcslen(InterfaceTable[Index].ProviderName) + 1) * sizeof(WCHAR));
+            RegSetValueExW(hKey, L"CLSID", 0, REG_SZ, (const BYTE*)pStr, (wcslen(pStr)+1) * sizeof(WCHAR));
+            RegCloseKey(hKey);
+        }
+
+
+
+
         CoTaskMemFree(pStr);
         Index++;
     }while(InterfaceTable[Index].lpfnCI != 0);
 
     RegCloseKey(hClass);
+    RegCloseKey(hInstance);
     return hr;
 }
 
index c9abe7a..828cfb4 100644 (file)
@@ -28,6 +28,7 @@ typedef struct
 {
     const GUID* riid;
     LPFNCREATEINSTANCE lpfnCI;
+    LPCWSTR ProviderName;
 } INTERFACE_TABLE;
 
 /* classfactory.cpp */
index 1875c51..78a7306 100644 (file)
@@ -854,7 +854,7 @@ SampleGrabber_ISampleGrabber_GetCurrentBuffer(ISampleGrabber *iface, LONG *bufSi
 static HRESULT WINAPI
 SampleGrabber_ISampleGrabber_GetCurrentSample(ISampleGrabber *iface, IMediaSample **sample)
 {
-    /* MS doesn't implement it either, noone should call it */
+    /* MS doesn't implement it either, no one should call it */
     WARN("(%p): not implemented\n", sample);
     return E_NOTIMPL;
 }
@@ -1264,7 +1264,7 @@ SampleGrabber_IPin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **mtypes)
     TRACE("(%p)->(%p)\n", This, mtypes);
     if (!mtypes)
         return E_POINTER;
-    *mtypes = mediaenum_create(This->sg->pin_in.pair ? &This->sg->mtype : (const AM_MEDIA_TYPE *)NULL);
+    *mtypes = mediaenum_create(This->sg->pin_in.pair ? &This->sg->mtype : NULL);
     return *mtypes ? S_OK : E_OUTOFMEMORY;
 }
 
index 68b1908..8469bbc 100644 (file)
@@ -203,7 +203,7 @@ static HRESULT AVIDec_ConnectInput(InputPin *pin, const AM_MEDIA_TYPE * pmt)
             bmi = &format2->bmiHeader;
         else
             goto failed;
-        TRACE("Fourcc: %s\n", debugstr_an((char *)&pmt->subtype.Data1, 4));
+        TRACE("Fourcc: %s\n", debugstr_an((const char *)&pmt->subtype.Data1, 4));
 
         This->hvid = ICLocate(pmt->majortype.Data1, pmt->subtype.Data1, bmi, NULL, ICMODE_DECOMPRESS);
         if (This->hvid)
index faa844b..42ec2ae 100644 (file)
@@ -692,7 +692,7 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE
                     amt.formattype = FORMAT_WaveFormatEx;
                     break;
                 default:
-                    FIXME("fccType %.4s not handled yet\n", (char *)&pStrHdr->fccType);
+                    FIXME("fccType %.4s not handled yet\n", (const char *)&pStrHdr->fccType);
                     amt.formattype = FORMAT_None;
                 }
                 amt.majortype = MEDIATYPE_Video;
@@ -793,7 +793,7 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE
             TRACE("bIndexSubType: %hd\n", pIndex->bIndexSubType);
             TRACE("bIndexType: %hd\n", pIndex->bIndexType);
             TRACE("nEntriesInUse: %u\n", pIndex->nEntriesInUse);
-            TRACE("dwChunkId: %.4s\n", (char *)&pIndex->dwChunkId);
+            TRACE("dwChunkId: %.4s\n", (const char *)&pIndex->dwChunkId);
             if (pIndex->dwReserved[0])
                 TRACE("dwReserved[0]: %u\n", pIndex->dwReserved[0]);
             if (pIndex->dwReserved[2])
index 9dcb999..1451219 100644 (file)
@@ -1518,7 +1518,7 @@ LdrpGetOrLoadModule(PWCHAR SearchPath,
        if (!NT_SUCCESS(Status))
          {
            ULONG ErrorResponse;
-           ULONG_PTR ErrorParameter = (ULONG_PTR)&DllName;
+           ULONG_PTR ErrorParameter = (ULONG_PTR)&AnsiDllName;
 
            DPRINT1("failed to load %wZ\n", &DllName);
 
index 63625d5..2b45834 100644 (file)
@@ -6,7 +6,7 @@
 8 stub ADsBuildVarArrayInt
 9 stdcall ADsOpenObject(wstr wstr wstr long ptr ptr)
 12 stub ADsSetLastError
-13 stub ADsGetLastError
+13 stdcall ADsGetLastError(ptr ptr long ptr long)
 14 stub AllocADsMem
 15 stdcall FreeADsMem(ptr)
 16 stub ReallocADsMem
index 9c03ac1..2fa4ec7 100644 (file)
@@ -94,6 +94,15 @@ HRESULT WINAPI ADsOpenObject(LPCWSTR lpszPathName, LPCWSTR lpszUserName, LPCWSTR
     return E_NOTIMPL;
 }
 
+/*****************************************************
+ * ADsGetLastError    [ACTIVEDS.13]
+ */
+HRESULT WINAPI ADsGetLastError(LPDWORD perror, LPWSTR errorbuf, DWORD errorbuflen, LPWSTR namebuf, DWORD namebuflen)
+{
+    FIXME("(%p,%p,%d,%p,%d)!stub\n", perror, errorbuf, errorbuflen, namebuf, namebuflen);
+    return E_NOTIMPL;
+}
+
 /*****************************************************
  * FreeADsMem             [ACTIVEDS.15]
  */
index f5272b5..c8b28ca 100644 (file)
@@ -31,7 +31,6 @@
        <file>actxprxy_ocmm.idl</file>
        <file>actxprxy_servprov.idl</file>
        <!-- file>actxprxy_shobjidl.idl</file -->
-       <file>actxprxy_urlhist.idl
-</file>
+       <file>actxprxy_urlhist.idl</file>
 </module>
 </group>
index 2afc746..616713c 100644 (file)
@@ -950,7 +950,7 @@ HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd,
     TRACE("(%s %p %p %p %p %p %p)\n", debugstr_w(lpszName), hWnd, pStream, 
             ppUnkContainer, ppUnkControl, iidSink, punkSink);
 
-    hRes = CLSIDFromString( (LPOLESTR) lpszName, &controlId );
+    hRes = CLSIDFromString( lpszName, &controlId );
     if ( FAILED(hRes) )
         hRes = CLSIDFromProgID( lpszName, &controlId );
     if ( SUCCEEDED( hRes ) )
index d86578c..b13fcb9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Top level resource file for avifil32.dll
  *
- * Copyright 2002 Michael Günnewig
+ * Copyright 2002 Michael Günnewig
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "windef.h"
-#include "winbase.h"
-#include "winuser.h"
-#include "winver.h"
 #include "avifile_private.h"
 
 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
index de64f02..b68ab15 100644 (file)
@@ -77,7 +77,7 @@ THOSE_ZIP_CONSTS;
 
 struct fdi_file {
   struct fdi_file *next;               /* next file in sequence          */
-  LPCSTR filename;                     /* output name of file            */
+  LPSTR filename;                     /* output name of file            */
   int    fh;                           /* open file handle or NULL       */
   cab_ULONG length;                    /* uncompressed length of file    */
   cab_ULONG offset;                    /* uncompressed offset in folder  */
@@ -2301,7 +2301,7 @@ static void free_decompression_mem(HFDI hfdi,
     }
     while (CAB(firstfile)) {
       file = CAB(firstfile);
-      if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
+      if (file->filename) PFDI_FREE(hfdi, file->filename);
       CAB(firstfile) = CAB(firstfile)->next;
       PFDI_FREE(hfdi, file);
     }
index 58b57cc..64cb393 100644 (file)
@@ -176,7 +176,7 @@ static SIZE MemDialogSize = { 0, 0}; /* keep size of the (resizable) dialog */
 /* Internal functions used by the dialog */
 static LRESULT FILEDLG95_ResizeControls(HWND hwnd, WPARAM wParam, LPARAM lParam);
 static LRESULT FILEDLG95_FillControls(HWND hwnd, WPARAM wParam, LPARAM lParam);
-static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam, LPARAM lParam);
+static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam);
 static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd);
 static BOOL    FILEDLG95_OnOpen(HWND hwnd);
 static LRESULT FILEDLG95_InitControls(HWND hwnd);
@@ -240,7 +240,7 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
 {
 
     LRESULT lRes;
-    LPCVOID template;
+    LPVOID template;
     HRSRC hRes;
     HANDLE hDlgTmpl = 0;
     HRESULT hr;
@@ -991,7 +991,7 @@ static LRESULT FILEDLG95_OnWMGetMMI( HWND hwnd, LPMINMAXINFO mmiptr)
  * vertically or horizontally to get out of the way. Only the "grip"
  * is moved in both directions to stay in the corner.
  */
-static LRESULT FILEDLG95_OnWMSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT FILEDLG95_OnWMSize(HWND hwnd, WPARAM wParam)
 {
     RECT rc, rcview;
     int chgx, chgy;
@@ -1223,11 +1223,11 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
          return 0;
        }
     case WM_SIZE:
-      return FILEDLG95_OnWMSize(hwnd, wParam, lParam);
+      return FILEDLG95_OnWMSize(hwnd, wParam);
     case WM_GETMINMAXINFO:
       return FILEDLG95_OnWMGetMMI( hwnd, (LPMINMAXINFO)lParam);
     case WM_COMMAND:
-      return FILEDLG95_OnWMCommand(hwnd, wParam, lParam);
+      return FILEDLG95_OnWMCommand(hwnd, wParam);
     case WM_DRAWITEM:
       {
         switch(((LPDRAWITEMSTRUCT)lParam)->CtlID)
@@ -1733,7 +1733,7 @@ void FILEDLG95_Clean(HWND hwnd)
  *
  * WM_COMMAND message handler
  */
-static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam)
 {
   WORD wNotifyCode = HIWORD(wParam); /* notification code */
   WORD wID = LOWORD(wParam);         /* item, control, or accelerator identifier */
@@ -3799,7 +3799,7 @@ BOOL FD32_GetTemplate(PFD31_DATA lfs)
 /***********************************************************************
  *                              FD32_WMMeasureItem           [internal]
  */
-static LONG FD32_WMMeasureItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
+static LONG FD32_WMMeasureItem(LPARAM lParam)
 {
     LPMEASUREITEMSTRUCT lpmeasure;
 
@@ -3832,7 +3832,7 @@ static INT_PTR CALLBACK FD32_FileOpenDlgProc(HWND hWnd, UINT wMsg,
         return FD31_WMInitDialog(hWnd, wParam, lParam);
 
     case WM_MEASUREITEM:
-        return FD32_WMMeasureItem(hWnd, wParam, lParam);
+        return FD32_WMMeasureItem(lParam);
 
     case WM_DRAWITEM:
         return FD31_WMDrawItem(hWnd, wParam, lParam, !lfs->open, (DRAWITEMSTRUCT *)lParam);
index 1ad881c..80f1ad9 100644 (file)
@@ -766,7 +766,7 @@ static LRESULT CFn_WMInitDialog(HWND hDlg, LPARAM lParam, LPCHOOSEFONTW lpcf)
 /***********************************************************************
  *           CFn_WMMeasureItem                           [internal]
  */
-static LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
+static LRESULT CFn_WMMeasureItem(HWND hDlg, LPARAM lParam)
 {
     HDC hdc;
     HFONT hfontprev;
@@ -794,7 +794,7 @@ static LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
 /***********************************************************************
  *           CFn_WMDrawItem                              [internal]
  */
-static LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
+static LRESULT CFn_WMDrawItem(LPARAM lParam)
 {
     HBRUSH hBrush;
     WCHAR buffer[40];
@@ -1190,9 +1190,9 @@ static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
     switch (uMsg)
     {
     case WM_MEASUREITEM:
-        return CFn_WMMeasureItem(hDlg, wParam, lParam);
+        return CFn_WMMeasureItem(hDlg,lParam);
     case WM_DRAWITEM:
-        return CFn_WMDrawItem(hDlg, wParam, lParam);
+        return CFn_WMDrawItem(lParam);
     case WM_COMMAND:
         return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
     case WM_DESTROY:
@@ -1239,9 +1239,9 @@ static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam,
     switch (uMsg)
     {
     case WM_MEASUREITEM:
-        return CFn_WMMeasureItem(hDlg, wParam, lParam);
+        return CFn_WMMeasureItem(hDlg, lParam);
     case WM_DRAWITEM:
-        return CFn_WMDrawItem(hDlg, wParam, lParam);
+        return CFn_WMDrawItem(lParam);
     case WM_COMMAND:
         return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
     case WM_DESTROY:
index f653251..74a06ff 100644 (file)
@@ -1504,7 +1504,7 @@ static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg,
  *                              PRINTDLG_WMCommand               [internal]
  */
 static LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam,
-                                   LPARAM lParam, PRINT_PTRA* PrintStructures)
+                                   PRINT_PTRA* PrintStructures)
 {
     LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
     UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4;
@@ -1658,7 +1658,7 @@ static LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam,
 }
 
 static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam,
-                       LPARAM lParam, PRINT_PTRW* PrintStructures)
+                                  PRINT_PTRW* PrintStructures)
 {
     LPPRINTDLGW lppd = PrintStructures->lpPrintDlg;
     UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4;
@@ -1846,7 +1846,7 @@ static INT_PTR CALLBACK PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
 
     switch (uMsg) {
     case WM_COMMAND:
-        return PRINTDLG_WMCommandA(hDlg, wParam, lParam, PrintStructures);
+        return PRINTDLG_WMCommandA(hDlg, wParam, PrintStructures);
 
     case WM_DESTROY:
        DestroyIcon(PrintStructures->hCollateIcon);
@@ -1892,7 +1892,7 @@ static INT_PTR CALLBACK PrintDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam,
 
     switch (uMsg) {
     case WM_COMMAND:
-        return PRINTDLG_WMCommandW(hDlg, wParam, lParam, PrintStructures);
+        return PRINTDLG_WMCommandW(hDlg, wParam, PrintStructures);
 
     case WM_DESTROY:
        DestroyIcon(PrintStructures->hCollateIcon);
index 4a6504a..7a23dd9 100644 (file)
@@ -99,8 +99,7 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
 
     TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes);
     needed = bytes + pad_bytes + 1;
-    if (sep)
-        needed += (needed / 64 + 1) * strlen(sep);
+    needed += (needed / 64 + 1) * strlen(sep);
 
     if (needed > *out_len)
     {
@@ -117,7 +116,7 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
     i = 0;
     while (div > 0)
     {
-        if (sep && i && i % 64 == 0)
+        if (i && i % 64 == 0)
         {
             strcpy(ptr, sep);
             ptr += strlen(sep);
@@ -163,8 +162,7 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
             *ptr++ = '=';
             break;
     }
-    if (sep)
-        strcpy(ptr, sep);
+    strcpy(ptr, sep);
 
     return ERROR_SUCCESS;
 }
@@ -180,7 +178,7 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
     if (dwFlags & CRYPT_STRING_NOCR)
         sep = lf;
     else if (dwFlags & CRYPT_STRING_NOCRLF)
-        sep = NULL;
+        sep = "";
     else
         sep = crlf;
     switch (dwFlags & 0x0fffffff)
@@ -204,8 +202,6 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
 
     charsNeeded = 0;
     encodeBase64A(pbBinary, cbBinary, sep, NULL, &charsNeeded);
-    if (sep)
-        charsNeeded += strlen(sep);
     if (header)
         charsNeeded += strlen(header) + strlen(sep);
     if (trailer)
@@ -219,11 +215,8 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
         {
             strcpy(ptr, header);
             ptr += strlen(ptr);
-            if (sep)
-            {
-                strcpy(ptr, sep);
-                ptr += strlen(sep);
-            }
+            strcpy(ptr, sep);
+            ptr += strlen(sep);
         }
         encodeBase64A(pbBinary, cbBinary, sep, ptr, &size);
         ptr += size - 1;
@@ -231,11 +224,8 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary,
         {
             strcpy(ptr, trailer);
             ptr += strlen(ptr);
-            if (sep)
-            {
-                strcpy(ptr, sep);
-                ptr += strlen(sep);
-            }
+            strcpy(ptr, sep);
+            ptr += strlen(sep);
         }
         *pcchString = charsNeeded - 1;
     }
@@ -304,8 +294,7 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep,
 
     TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes);
     needed = bytes + pad_bytes + 1;
-    if (sep)
-        needed += (needed / 64 + 1) * strlenW(sep);
+    needed += (needed / 64 + 1) * strlenW(sep);
 
     if (needed > *out_len)
     {
@@ -322,7 +311,7 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep,
     i = 0;
     while (div > 0)
     {
-        if (sep && i && i % 64 == 0)
+        if (i && i % 64 == 0)
         {
             strcpyW(ptr, sep);
             ptr += strlenW(sep);
@@ -368,8 +357,7 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep,
             *ptr++ = '=';
             break;
     }
-    if (sep)
-        strcpyW(ptr, sep);
+    strcpyW(ptr, sep);
 
     return ERROR_SUCCESS;
 }
@@ -377,7 +365,7 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep,
 static BOOL BinaryToBase64W(const BYTE *pbBinary,
  DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString)
 {
-    static const WCHAR crlf[] = { '\r','\n',0 }, lf[] = { '\n',0 };
+    static const WCHAR crlf[] = { '\r','\n',0 }, lf[] = { '\n',0 }, empty[] = {0};
     BOOL ret = TRUE;
     LPCWSTR header = NULL, trailer = NULL, sep;
     DWORD charsNeeded;
@@ -385,7 +373,7 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary,
     if (dwFlags & CRYPT_STRING_NOCR)
         sep = lf;
     else if (dwFlags & CRYPT_STRING_NOCRLF)
-        sep = NULL;
+        sep = empty;
     else
         sep = crlf;
     switch (dwFlags & 0x0fffffff)
@@ -409,8 +397,6 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary,
 
     charsNeeded = 0;
     encodeBase64W(pbBinary, cbBinary, sep, NULL, &charsNeeded);
-    if (sep)
-        charsNeeded += strlenW(sep);
     if (header)
         charsNeeded += strlenW(header) + strlenW(sep);
     if (trailer)
@@ -424,11 +410,8 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary,
         {
             strcpyW(ptr, header);
             ptr += strlenW(ptr);
-            if (sep)
-            {
-                strcpyW(ptr, sep);
-                ptr += strlenW(sep);
-            }
+            strcpyW(ptr, sep);
+            ptr += strlenW(sep);
         }
         encodeBase64W(pbBinary, cbBinary, sep, ptr, &size);
         ptr += size - 1;
@@ -436,11 +419,8 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary,
         {
             strcpyW(ptr, trailer);
             ptr += strlenW(ptr);
-            if (sep)
-            {
-                strcpyW(ptr, sep);
-                ptr += strlenW(sep);
-            }
+            strcpyW(ptr, sep);
+            ptr += strlenW(sep);
         }
         *pcchString = charsNeeded - 1;
     }
index fb3d36e..655a5b2 100644 (file)
@@ -523,9 +523,11 @@ static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
 
                 for (i = 0; i < cItem; i++)
                 {
-                    bytesNeeded += items[i].size;
+                    if (items[i].size > items[i].minSize)
+                        bytesNeeded += items[i].size - items[i].minSize;
                     structSize = max( structSize, items[i].offset + items[i].minSize );
                 }
+                bytesNeeded += structSize;
                 if (pcbDecoded)
                     *pcbDecoded = 1 + lenBytes + cbDecoded;
                 if (!pvStructInfo)
index 2c29b44..aa7a56e 100644 (file)
@@ -1,6 +1,6 @@
 /* FILE:        dll/win32/devmgr/lang/cs-CZ.rc
  * TRANSLATOR:  Radek Liska aka Black_Fox (radekliska at gmail dot com)
- * UPDATED:     2008-06-24
+ * UPDATED:     2010-01-07
  */
 
 LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
@@ -202,7 +202,7 @@ END
 
 IDD_DEVICEDETAILS DIALOGEX DISCARDABLE  0, 0, 252, 218
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Details"
+CAPTION "Detaily"
 FONT 8, "MS Shell Dlg"
 BEGIN
     ICON "", IDC_DEVICON, 7, 7, 20, 20
@@ -215,7 +215,7 @@ END
 
 IDD_DEVICERESOURCES DIALOGEX DISCARDABLE  0, 0, 252, 218
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Resources"
+CAPTION "Prostøedky"
 FONT 8, "MS Shell Dlg"
 BEGIN
     ICON "", IDC_DEVICON, 7, 7, 20, 20
@@ -224,7 +224,7 @@ END
 
 IDD_DEVICEPOWER DIALOGEX DISCARDABLE  0, 0, 252, 218
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Power"
+CAPTION "Napájení"
 FONT 8, "MS Shell Dlg"
 BEGIN
     ICON "", IDC_DEVICON, 7, 7, 20, 20
index f45a0dd..5cc0987 100644 (file)
@@ -292,4 +292,91 @@ int FASTCALL DocumentEventEx(PVOID,HANDLE,HDC,int,ULONG,PVOID,ULONG,PVOID);
 BOOL FASTCALL EndPagePrinterEx(PVOID,HANDLE);
 BOOL FASTCALL LoadTheSpoolerDrv(VOID);
 
+
+FORCEINLINE
+PVOID
+GdiAllocBatchCommand(
+    HDC hdc,
+    USHORT Cmd)
+{
+    PTEB pTeb;
+    ULONG ulSize;
+    PGDIBATCHHDR pHdr;
+
+    /* Get a pointer to the TEB */
+    pTeb = NtCurrentTeb();
+
+    /* Check if we have a valid environment */
+    if (!pTeb || !pTeb->Win32ThreadInfo) return NULL;
+
+    /* Do we use a DC? */
+    if (hdc)
+    {
+        /* If the batch DC is NULL, we set this one as the new one */
+        if (!pTeb->GdiTebBatch.HDC) pTeb->GdiTebBatch.HDC = hdc;
+
+        /* If not, check if the batch DC equal to our DC */
+        else if (pTeb->GdiTebBatch.HDC != hdc) return NULL;
+    }
+
+    /* Get the size of the entry */
+    switch(Cmd)
+    {
+        case GdiBCPatBlt:
+            ulSize = 0;
+            break;
+        case GdiBCPolyPatBlt:
+            ulSize = 0;
+            break;
+        case GdiBCTextOut:
+            ulSize = 0;
+            break;
+        case GdiBCExtTextOut:
+            ulSize = 0;
+            break;
+        case GdiBCSetBrushOrg:
+            ulSize = 0;
+            break;
+        case GdiBCExtSelClipRgn:
+            ulSize = 0;
+            break;
+        case GdiBCSelObj:
+            ulSize = sizeof(GDIBSOBJECT);
+            break;
+        case GdiBCDelRgn:
+            ulSize = sizeof(GDIBSOBJECT);
+            break;
+        case GdiBCDelObj:
+            ulSize = sizeof(GDIBSOBJECT);
+            break;
+        default:
+            return NULL;
+    }
+
+    /* Unsupported operation */
+    if (ulSize == 0) return NULL;
+
+    /* Check if the buffer is full */
+    if ((pTeb->GdiBatchCount >= GDI_BatchLimit) ||
+        ((pTeb->GdiTebBatch.Offset + ulSize) > GDIBATCHBUFSIZE))
+    {
+        /* Call win32k, the kernel will call NtGdiFlushUserBatch to flush
+           the current batch */
+        NtGdiFlush();
+    }
+
+    /* Get the head of the entry */
+    pHdr = (PVOID)((PUCHAR)pTeb->GdiTebBatch.Buffer + pTeb->GdiTebBatch.Offset);
+
+    /* Update Offset and batch count */
+    pTeb->GdiTebBatch.Offset += ulSize;
+    pTeb->GdiBatchCount++;
+
+    /* Fill in the core fields */
+    pHdr->Cmd = Cmd;
+    pHdr->Size = ulSize;
+
+    return pHdr;
+}
+
 /* EOF */
index 2d90f60..ddc33e5 100644 (file)
@@ -1540,7 +1540,6 @@ SelectObject(HDC hDC,
     PDC_ATTR pDc_Attr;
     HGDIOBJ hOldObj = NULL;
     UINT uType;
-//    PTEB pTeb;
 
     if(!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
     {
@@ -1582,29 +1581,23 @@ SelectObject(HDC hDC,
         case GDI_OBJECT_TYPE_FONT:
             hOldObj = pDc_Attr->hlfntNew;
             if (hOldObj == hGdiObj) return hOldObj;
-#if 0
+
             pDc_Attr->ulDirty_ &= ~SLOW_WIDTHS;
             pDc_Attr->ulDirty_ |= DIRTY_CHARSET;
             pDc_Attr->hlfntNew = hGdiObj;
-            pTeb = NtCurrentTeb();
-            if (((pTeb->GdiTebBatch.HDC == 0) ||
-                 (pTeb->GdiTebBatch.HDC == hDC)) &&
-                ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE) &&
-               (!(pDc_Attr->ulDirty_ & DC_DIBSECTION)))
+
+            if (!(pDc_Attr->ulDirty_ & DC_DIBSECTION))
             {
-              PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
-                                                pTeb->GdiTebBatch.Offset);
-              pgO->gbHdr.Cmd = GdiBCSelObj;
-              pgO->gbHdr.Size = sizeof(GDIBSOBJECT);
-              pgO->hgdiobj = hGdiObj;
-
-              pTeb->GdiTebBatch.Offset += sizeof(GDIBSOBJECT);
-              pTeb->GdiTebBatch.HDC = hDC;
-              pTeb->GdiBatchCount++;
-              if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
-              return hOldObj;
+                PGDIBSOBJECT pgO;
+
+                pgO = GdiAllocBatchCommand(hDC, GdiBCSelObj);
+                if (pgO)
+                {
+                    pgO->hgdiobj = hGdiObj;
+                    return hOldObj;
+                }
             }
-#endif
+
             // default for select object font
             return NtGdiSelectFont(hDC, hGdiObj);
 
index e1f187a..b8d7077 100644 (file)
@@ -104,31 +104,20 @@ BOOL
 FASTCALL
 DeleteRegion( HRGN hRgn )
 {
-//#if 0
   PRGN_ATTR Rgn_Attr;
 
   if ((GdiGetHandleUserData((HGDIOBJ) hRgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr)) &&
       ( Rgn_Attr != NULL ))
   {
-     PTEB pTeb = NtCurrentTeb();
-     if (pTeb->Win32ThreadInfo != NULL)
-     {
-        if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE)
-        {
-           PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
-                                                      pTeb->GdiTebBatch.Offset);
-           pgO->gbHdr.Cmd = GdiBCDelRgn;
-           pgO->gbHdr.Size = sizeof(GDIBSOBJECT);
-           pgO->hgdiobj = (HGDIOBJ)hRgn;
-
-           pTeb->GdiTebBatch.Offset += sizeof(GDIBSOBJECT);
-           pTeb->GdiBatchCount++;
-           if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
-           return TRUE;
-        }
-     }
+      PGDIBSOBJECT pgO;
+      
+      pgO = GdiAllocBatchCommand(NULL, GdiBCDelRgn);
+      if (pgO)
+      {
+          pgO->hgdiobj = (HGDIOBJ)hRgn;
+          return TRUE;
+      }
   }
-//#endif
   return NtGdiDeleteObjectApp((HGDIOBJ) hRgn);
 }
 
@@ -581,8 +570,110 @@ INT
 WINAPI
 ExtSelectClipRgn( IN HDC hdc, IN HRGN hrgn, IN INT iMode)
 {
-    /* FIXME some part need be done on user mode size */
-    return NtGdiExtSelectClipRgn(hdc,hrgn, iMode);
+  INT Ret;
+  HRGN NewRgn = NULL;
+
+#if 0
+// Handle something other than a normal dc object.
+  if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
+  {
+    if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
+      return MFDRV_ExtSelectClipRgn( hdc, );
+    else
+    {
+      PLDC pLDC = GdiGetLDC(hdc);
+      if ( pLDC )
+      {
+         if (pLDC->iType != LDC_EMFLDC || EMFDRV_ExtSelectClipRgn( hdc, ))
+             return NtGdiExtSelectClipRgn(hdc, );
+      }
+      else
+        SetLastError(ERROR_INVALID_HANDLE);
+      return ERROR;
+    }
+  }
+#endif
+#if 0
+  if ( hrgn )
+  {
+     if ( GetLayout(hdc) & LAYOUT_RTL )
+     {
+        if ( MirrorRgnDC(hdc, hrgn, &NewRgn) )
+        {
+           if ( NewRgn ) hrgn = NewRgn;
+        }
+     }
+  }
+#endif
+  /* Batch handles RGN_COPY only! */
+  if (iMode == RGN_COPY)
+  {
+#if 0
+     PDC_ATTR pDc_Attr;
+     PRGN_ATTR pRgn_Attr = NULL;
+
+     /* hrgn can be NULL unless the RGN_COPY mode is specified. */
+     if (hrgn)
+        GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr);
+
+     if ( GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &pDc_Attr) &&
+          pDc_Attr )
+     {
+        PGDI_TABLE_ENTRY pEntry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hdc);
+        PTEB pTeb = NtCurrentTeb();
+        
+        if ( pTeb->Win32ThreadInfo != NULL &&
+             pTeb->GdiTebBatch.HDC == hdc &&
+            !(pDc_Attr->ulDirty_ & DC_DIBSECTION) &&
+            !(pEntry->Flags & GDI_ENTRY_VALIDATE_VIS) )
+        {
+           if (!hrgn ||
+                (hrgn && pRgn_Attr && pRgn_Attr->Flags <= SIMPLEREGION) )
+           {
+              if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSEXTSELCLPRGN)) <= GDIBATCHBUFSIZE)
+              {
+                 PGDIBSEXTSELCLPRGN pgO = (PGDIBSEXTSELCLPRGN)(&pTeb->GdiTebBatch.Buffer[0] +
+                                                      pTeb->GdiTebBatch.Offset);
+                 pgO->gbHdr.Cmd = GdiBCExtSelClipRgn;
+                 pgO->gbHdr.Size = sizeof(GDIBSEXTSELCLPRGN);
+                 pgO->fnMode = iMode;
+
+                 if ( hrgn && pRgn_Attr )
+                 {
+                    Ret = pRgn_Attr->Flags;
+
+                    if ( pDc_Attr->VisRectRegion.Rect.left   >= pRgn_Attr->Rect.right  ||
+                         pDc_Attr->VisRectRegion.Rect.top    >= pRgn_Attr->Rect.bottom ||
+                         pDc_Attr->VisRectRegion.Rect.right  <= pRgn_Attr->Rect.left   ||
+                         pDc_Attr->VisRectRegion.Rect.bottom <= pRgn_Attr->Rect.top )
+                       Ret = NULLREGION;
+
+                    pgO->left   = pRgn_Attr->Rect.left;
+                    pgO->top    = pRgn_Attr->Rect.top;
+                    pgO->right  = pRgn_Attr->Rect.right;
+                    pgO->bottom = pRgn_Attr->Rect.bottom;
+                 }
+                 else
+                 {
+                    Ret = pDc_Attr->VisRectRegion.Flags;
+                    pgO->fnMode |= 0x80000000; // Set no hrgn mode.
+                 }
+                 pTeb->GdiTebBatch.Offset += sizeof(GDIBSEXTSELCLPRGN);
+                 pTeb->GdiBatchCount++;
+                 if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
+                 if ( NewRgn ) DeleteObject(NewRgn);
+                 return Ret;
+              }
+           }
+        }
+     }
+#endif
+  }
+  Ret = NtGdiExtSelectClipRgn(hdc, hrgn, iMode);
+
+  if ( NewRgn ) DeleteObject(NewRgn);
+
+  return Ret;
 }
 
 /*
index 2d28004..67be6b4 100644 (file)
@@ -1194,6 +1194,16 @@ GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
     return NotImplemented;
 }
 
+GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorCount(GpPathGradient *brush, INT *count)
+{
+    TRACE("(%p, %p)\n", brush, count);
+
+    if (!brush || !count)
+       return InvalidParameter;
+
+    return NotImplemented;
+}
+
 GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient *brush,
     GpWrapMode *wrapmode)
 {
@@ -1559,7 +1569,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient *grad,
 }
 
 GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
-    *grad, ARGB *argb, INT *count)
+    *grad, GDIPCONST ARGB *argb, INT *count)
 {
     static int calls;
 
index fda5428..3a29771 100644 (file)
@@ -489,6 +489,7 @@ GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi,
     switch (font->unit)
     {
         case UnitPixel:
+        case UnitWorld:
             *height = font_height;
             break;
         case UnitPoint:
@@ -520,7 +521,7 @@ GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi,
 static INT CALLBACK is_font_installed_proc(const LOGFONTW *elf,
                             const TEXTMETRICW *ntm, DWORD type, LPARAM lParam)
 {
-    if (!ntm)
+    if (!ntm || type == RASTER_FONTTYPE)
     {
         return 1;
     }
@@ -642,12 +643,14 @@ GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily* FontFamily, GpFontFamily**
 GpStatus WINGDIPAPI GdipGetFamilyName (GDIPCONST GpFontFamily *family,
                                        WCHAR *name, LANGID language)
 {
+    static int lang_fixme;
+
     if (family == NULL)
          return InvalidParameter;
 
     TRACE("%p, %p, %d\n", family, name, language);
 
-    if (language != LANG_NEUTRAL)
+    if (language != LANG_NEUTRAL && !lang_fixme++)
         FIXME("No support for handling of multiple languages!\n");
 
     lstrcpynW (name, family->FamilyName, LF_FACESIZE);
@@ -826,15 +829,21 @@ GpStatus WINGDIPAPI GdipGetGenericFontFamilySerif(GpFontFamily **nativeFamily)
  */
 GpStatus WINGDIPAPI GdipGetGenericFontFamilySansSerif(GpFontFamily **nativeFamily)
 {
-    /* FIXME: On Windows this is called Microsoft Sans Serif, this shouldn't
-     * affect anything */
-    static const WCHAR MSSansSerif[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
+    GpStatus stat;
+    static const WCHAR MicrosoftSansSerif[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
+    static const WCHAR Tahoma[] = {'T','a','h','o','m','a','\0'};
 
     TRACE("(%p)\n", nativeFamily);
 
     if (nativeFamily == NULL) return InvalidParameter;
 
-    return GdipCreateFontFamilyFromName(MSSansSerif, NULL, nativeFamily);
+    stat = GdipCreateFontFamilyFromName(MicrosoftSansSerif, NULL, nativeFamily);
+
+    if (stat == FontFamilyNotFound)
+        /* FIXME: Microsoft Sans Serif is not installed on Wine. */
+        stat = GdipCreateFontFamilyFromName(Tahoma, NULL, nativeFamily);
+
+    return stat;
 }
 
 /*****************************************************************************
@@ -957,6 +966,9 @@ static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm,
     GpFontCollection* fonts = (GpFontCollection*)lParam;
     int i;
 
+    if (type == RASTER_FONTTYPE)
+        return 1;
+
     /* skip duplicates */
     for (i=0; i<fonts->count; i++)
         if (strcmpiW(lfw->lfFaceName, fonts->FontFamilies[i]->FamilyName) == 0)
index e6cea5a..14e7fbf 100644 (file)
 @ stub GdipGetPathGradientPresetBlendCount
 @ stdcall GdipGetPathGradientRect(ptr ptr)
 @ stdcall GdipGetPathGradientRectI(ptr ptr)
-@ stub GdipGetPathGradientSurroundColorCount
+@ stdcall GdipGetPathGradientSurroundColorCount(ptr ptr)
 @ stdcall GdipGetPathGradientSurroundColorsWithCount(ptr ptr ptr)
 @ stub GdipGetPathGradientTransform
 @ stdcall GdipGetPathGradientWrapMode(ptr ptr)
index ca1cba6..5ff7125 100644 (file)
@@ -78,6 +78,29 @@ static inline REAL deg2rad(REAL degrees)
     return M_PI * degrees / 180.0;
 }
 
+static inline ARGB color_over(ARGB bg, ARGB fg)
+{
+    BYTE b, g, r, a;
+    BYTE bg_alpha, fg_alpha;
+
+    fg_alpha = (fg>>24)&0xff;
+
+    if (fg_alpha == 0xff) return fg;
+
+    if (fg_alpha == 0) return bg;
+
+    bg_alpha = (((bg>>24)&0xff) * (0xff-fg_alpha)) / 0xff;
+
+    if (bg_alpha == 0) return fg;
+
+    a = bg_alpha + fg_alpha;
+    b = ((bg&0xff)*bg_alpha + (fg&0xff)*fg_alpha)*0xff/a;
+    g = (((bg>>8)&0xff)*bg_alpha + ((fg>>8)&0xff)*fg_alpha)*0xff/a;
+    r = (((bg>>16)&0xff)*bg_alpha + ((fg>>16)&0xff)*fg_alpha)*0xff/a;
+
+    return (a<<24)|(r<<16)|(g<<8)|b;
+}
+
 extern const char *debugstr_rectf(CONST RectF* rc);
 
 extern const char *debugstr_pointf(CONST PointF* pt);
@@ -112,6 +135,7 @@ struct GpGraphics{
     HDC hdc;
     HWND hwnd;
     BOOL owndc;
+    GpImage *image;
     SmoothingMode smoothing;
     CompositingQuality compqual;
     InterpolationMode interpolation;
index 1fd870e..7a6fad3 100644 (file)
@@ -173,6 +173,74 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
     }
 }
 
+/* Draw non-premultiplied ARGB data to the given graphics object */
+static GpStatus alpha_blend_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
+    const BYTE *src, INT src_width, INT src_height, INT src_stride)
+{
+    if (graphics->image && graphics->image->type == ImageTypeBitmap)
+    {
+        GpBitmap *dst_bitmap = (GpBitmap*)graphics->image;
+        INT x, y;
+
+        for (x=0; x<src_width; x++)
+        {
+            for (y=0; y<src_height; y++)
+            {
+                ARGB dst_color, src_color;
+                GdipBitmapGetPixel(dst_bitmap, x+dst_x, y+dst_y, &dst_color);
+                src_color = ((ARGB*)(src + src_stride * y))[x];
+                GdipBitmapSetPixel(dst_bitmap, x+dst_x, y+dst_y, color_over(dst_color, src_color));
+            }
+        }
+
+        return Ok;
+    }
+    else
+    {
+        HDC hdc;
+        HBITMAP hbitmap, old_hbm=NULL;
+        BITMAPINFOHEADER bih;
+        BYTE *temp_bits;
+        BLENDFUNCTION bf;
+
+        hdc = CreateCompatibleDC(0);
+
+        bih.biSize = sizeof(BITMAPINFOHEADER);
+        bih.biWidth = src_width;
+        bih.biHeight = -src_height;
+        bih.biPlanes = 1;
+        bih.biBitCount = 32;
+        bih.biCompression = BI_RGB;
+        bih.biSizeImage = 0;
+        bih.biXPelsPerMeter = 0;
+        bih.biYPelsPerMeter = 0;
+        bih.biClrUsed = 0;
+        bih.biClrImportant = 0;
+
+        hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS,
+            (void**)&temp_bits, NULL, 0);
+
+        convert_32bppARGB_to_32bppPARGB(src_width, src_height, temp_bits,
+            4 * src_width, src, src_stride);
+
+        old_hbm = SelectObject(hdc, hbitmap);
+
+        bf.BlendOp = AC_SRC_OVER;
+        bf.BlendFlags = 0;
+        bf.SourceConstantAlpha = 255;
+        bf.AlphaFormat = AC_SRC_ALPHA;
+
+        GdiAlphaBlend(graphics->hdc, dst_x, dst_y, src_width, src_height,
+            hdc, 0, 0, src_width, src_height, bf);
+
+        SelectObject(hdc, old_hbm);
+        DeleteDC(hdc);
+        DeleteObject(hbitmap);
+
+        return Ok;
+    }
+}
+
 static ARGB blend_colors(ARGB start, ARGB end, REAL position)
 {
     ARGB result=0;
@@ -1273,10 +1341,10 @@ GpStatus WINGDIPAPI GdipCreateMetafileFromWmf(HMETAFILE hwmf, BOOL delete,
     (*metafile)->bounds.X = ((REAL) placeable->BoundingBox.Left) / ((REAL) placeable->Inch);
     (*metafile)->bounds.Y = ((REAL) placeable->BoundingBox.Top) / ((REAL) placeable->Inch);
     (*metafile)->bounds.Width = ((REAL) (placeable->BoundingBox.Right
-                    - placeable->BoundingBox.Left)) / ((REAL) placeable->Inch);
+                    - placeable->BoundingBox.Left));
     (*metafile)->bounds.Height = ((REAL) (placeable->BoundingBox.Bottom
-                   - placeable->BoundingBox.Top)) / ((REAL) placeable->Inch);
-    (*metafile)->unit = UnitInch;
+                   - placeable->BoundingBox.Top));
+    (*metafile)->unit = UnitPixel;
 
     if(delete)
         DeleteMetaFile(hwmf);
@@ -1866,15 +1934,15 @@ GpStatus WINGDIPAPI GdipDrawImagePointsI(GpGraphics *graphics, GpImage *image,
     return NotImplemented;
 }
 
-/* FIXME: partially implemented (only works for rectangular parallelograms) */
 GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image,
      GDIPCONST GpPointF *points, INT count, REAL srcx, REAL srcy, REAL srcwidth,
      REAL srcheight, GpUnit srcUnit, GDIPCONST GpImageAttributes* imageAttributes,
      DrawImageAbort callback, VOID * callbackData)
 {
-    GpPointF ptf[3];
-    POINT pti[3];
+    GpPointF ptf[4];
+    POINT pti[4];
     REAL dx, dy;
+    GpStatus stat;
 
     TRACE("(%p, %p, %p, %d, %f, %f, %f, %f, %d, %p, %p, %p)\n", graphics, image, points,
           count, srcx, srcy, srcwidth, srcheight, srcUnit, imageAttributes, callback,
@@ -1887,10 +1955,13 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
         debugstr_pointf(&points[2]));
 
     memcpy(ptf, points, 3 * sizeof(GpPointF));
-    transform_and_round_points(graphics, pti, ptf, 3);
+    ptf[3].X = ptf[2].X + ptf[1].X - ptf[0].X;
+    ptf[3].Y = ptf[2].Y + ptf[1].Y - ptf[0].Y;
+    transform_and_round_points(graphics, pti, ptf, 4);
 
     if (image->picture)
     {
+        /* FIXME: partially implemented (only works for rectangular parallelograms) */
         if(srcUnit == UnitInch)
             dx = dy = (REAL) INCH_HIMETRIC;
         else if(srcUnit == UnitPixel){
@@ -1914,10 +1985,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
     }
     else if (image->type == ImageTypeBitmap && ((GpBitmap*)image)->hbitmap)
     {
-        HDC hdc;
         GpBitmap* bitmap = (GpBitmap*)image;
-        int temp_hdc=0, temp_bitmap=0;
-        HBITMAP hbitmap, old_hbm=NULL;
+        int use_software=0;
 
         if (srcUnit == UnitInch)
             dx = dy = 96.0; /* FIXME: use the image resolution */
@@ -1926,83 +1995,233 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
         else
             return NotImplemented;
 
-        if (!(bitmap->format == PixelFormat16bppRGB555 ||
-              bitmap->format == PixelFormat24bppRGB ||
-              bitmap->format == PixelFormat32bppRGB ||
-              bitmap->format == PixelFormat32bppPARGB))
+        if (imageAttributes ||
+            (graphics->image && graphics->image->type == ImageTypeBitmap) ||
+            ptf[1].Y != ptf[0].Y || ptf[2].X != ptf[0].X)
+            use_software = 1;
+
+        if (use_software)
         {
-            BITMAPINFOHEADER bih;
-            BYTE *temp_bits;
-            PixelFormat dst_format;
-
-            /* we can't draw a bitmap of this format directly */
-            hdc = CreateCompatibleDC(0);
-            temp_hdc = 1;
-            temp_bitmap = 1;
-
-            bih.biSize = sizeof(BITMAPINFOHEADER);
-            bih.biWidth = bitmap->width;
-            bih.biHeight = -bitmap->height;
-            bih.biPlanes = 1;
-            bih.biBitCount = 32;
-            bih.biCompression = BI_RGB;
-            bih.biSizeImage = 0;
-            bih.biXPelsPerMeter = 0;
-            bih.biYPelsPerMeter = 0;
-            bih.biClrUsed = 0;
-            bih.biClrImportant = 0;
-
-            hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS,
-                (void**)&temp_bits, NULL, 0);
+            RECT src_area, dst_area;
+            int i, x, y, stride;
+            GpMatrix *dst_to_src;
+            REAL m11, m12, m21, m22, mdx, mdy;
+            LPBYTE data;
+
+            src_area.left = srcx*dx;
+            src_area.top = srcy*dy;
+            src_area.right = (srcx+srcwidth)*dx;
+            src_area.bottom = (srcy+srcheight)*dy;
+
+            dst_area.left = dst_area.right = pti[0].x;
+            dst_area.top = dst_area.bottom = pti[0].y;
+            for (i=1; i<4; i++)
+            {
+                if (dst_area.left > pti[i].x) dst_area.left = pti[i].x;
+                if (dst_area.right < pti[i].x) dst_area.right = pti[i].x;
+                if (dst_area.top > pti[i].y) dst_area.top = pti[i].y;
+                if (dst_area.bottom < pti[i].y) dst_area.bottom = pti[i].y;
+            }
 
-            if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha))
-                dst_format = PixelFormat32bppPARGB;
-            else
-                dst_format = PixelFormat32bppRGB;
+            m11 = (ptf[1].X - ptf[0].X) / srcwidth;
+            m21 = (ptf[2].X - ptf[0].X) / srcheight;
+            mdx = ptf[0].X - m11 * srcx - m21 * srcy;
+            m12 = (ptf[1].Y - ptf[0].Y) / srcwidth;
+            m22 = (ptf[2].Y - ptf[0].Y) / srcheight;
+            mdy = ptf[0].Y - m12 * srcx - m22 * srcy;
 
-            convert_pixels(bitmap->width, bitmap->height,
-                bitmap->width*4, temp_bits, dst_format,
-                bitmap->stride, bitmap->bits, bitmap->format, bitmap->image.palette_entries);
-        }
-        else
-        {
-            hbitmap = bitmap->hbitmap;
-            hdc = bitmap->hdc;
-            temp_hdc = (hdc == 0);
-        }
+            stat = GdipCreateMatrix2(m11, m12, m21, m22, mdx, mdy, &dst_to_src);
+            if (stat != Ok) return stat;
 
-        if (temp_hdc)
-        {
-            if (!hdc) hdc = CreateCompatibleDC(0);
-            old_hbm = SelectObject(hdc, hbitmap);
-        }
+            stat = GdipInvertMatrix(dst_to_src);
+            if (stat != Ok)
+            {
+                GdipDeleteMatrix(dst_to_src);
+                return stat;
+            }
 
-        if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha))
-        {
-            BLENDFUNCTION bf;
+            data = GdipAlloc(sizeof(ARGB) * (dst_area.right - dst_area.left) * (dst_area.bottom - dst_area.top));
+            if (!data)
+            {
+                GdipDeleteMatrix(dst_to_src);
+                return OutOfMemory;
+            }
+
+            stride = sizeof(ARGB) * (dst_area.right - dst_area.left);
+
+            for (x=dst_area.left; x<dst_area.right; x++)
+            {
+                for (y=dst_area.top; y<dst_area.bottom; y++)
+                {
+                    GpPointF src_pointf;
+                    int src_x, src_y;
+                    ARGB *src_color;
+
+                    src_pointf.X = x;
+                    src_pointf.Y = y;
+
+                    GdipTransformMatrixPoints(dst_to_src, &src_pointf, 1);
+
+                    src_x = roundr(src_pointf.X);
+                    src_y = roundr(src_pointf.Y);
+
+                    src_color = (ARGB*)(data + stride * (y - dst_area.top) + sizeof(ARGB) * (x - dst_area.left));
+
+                    if (src_x < src_area.left || src_x >= src_area.right ||
+                        src_y < src_area.top || src_y >= src_area.bottom)
+                        /* FIXME: Use wrapmode */
+                        *src_color = 0;
+                    else
+                        GdipBitmapGetPixel(bitmap, src_x, src_y, src_color);
+                }
+            }
+
+            GdipDeleteMatrix(dst_to_src);
+
+            if (imageAttributes)
+            {
+                if (imageAttributes->colorkeys[ColorAdjustTypeBitmap].enabled ||
+                    imageAttributes->colorkeys[ColorAdjustTypeDefault].enabled)
+                {
+                    static int fixme;
+                    if (!fixme++)
+                        FIXME("Color keying not implemented\n");
+                }
+
+                if (imageAttributes->colorremaptables[ColorAdjustTypeBitmap].enabled ||
+                    imageAttributes->colorremaptables[ColorAdjustTypeDefault].enabled)
+                {
+                    const struct color_remap_table *table;
+
+                    if (imageAttributes->colorremaptables[ColorAdjustTypeBitmap].enabled)
+                        table = &imageAttributes->colorremaptables[ColorAdjustTypeBitmap];
+                    else
+                        table = &imageAttributes->colorremaptables[ColorAdjustTypeDefault];
+
+                    for (x=dst_area.left; x<dst_area.right; x++)
+                        for (y=dst_area.top; y<dst_area.bottom; y++)
+                        {
+                            ARGB *src_color;
+                            src_color = (ARGB*)(data + stride * (y - dst_area.top) + sizeof(ARGB) * (x - dst_area.left));
+                            for (i=0; i<table->mapsize; i++)
+                            {
+                                if (*src_color == table->colormap[i].oldColor.Argb)
+                                {
+                                    *src_color = table->colormap[i].newColor.Argb;
+                                    break;
+                                }
+                            }
+                        }
+                }
+
+                if (imageAttributes->colormatrices[ColorAdjustTypeBitmap].enabled ||
+                    imageAttributes->colormatrices[ColorAdjustTypeDefault].enabled)
+                {
+                    static int fixme;
+                    if (!fixme++)
+                        FIXME("Color transforms not implemented\n");
+                }
+
+                if (imageAttributes->gamma_enabled[ColorAdjustTypeBitmap] ||
+                    imageAttributes->gamma_enabled[ColorAdjustTypeDefault])
+                {
+                    static int fixme;
+                    if (!fixme++)
+                        FIXME("Gamma adjustment not implemented\n");
+                }
+            }
+
+            stat = alpha_blend_pixels(graphics, dst_area.left, dst_area.top,
+                data, dst_area.right - dst_area.left, dst_area.bottom - dst_area.top, stride);
 
-            bf.BlendOp = AC_SRC_OVER;
-            bf.BlendFlags = 0;
-            bf.SourceConstantAlpha = 255;
-            bf.AlphaFormat = AC_SRC_ALPHA;
+            GdipFree(data);
 
-            GdiAlphaBlend(graphics->hdc, pti[0].x, pti[0].y, pti[1].x-pti[0].x, pti[2].y-pti[0].y,
-                hdc, srcx*dx, srcy*dy, srcwidth*dx, srcheight*dy, bf);
+            return stat;
         }
         else
         {
-            StretchBlt(graphics->hdc, pti[0].x, pti[0].y, pti[1].x-pti[0].x, pti[2].y-pti[0].y,
-                hdc, srcx*dx, srcy*dy, srcwidth*dx, srcheight*dy, SRCCOPY);
-        }
+            HDC hdc;
+            int temp_hdc=0, temp_bitmap=0;
+            HBITMAP hbitmap, old_hbm=NULL;
+
+            if (!(bitmap->format == PixelFormat16bppRGB555 ||
+                  bitmap->format == PixelFormat24bppRGB ||
+                  bitmap->format == PixelFormat32bppRGB ||
+                  bitmap->format == PixelFormat32bppPARGB))
+            {
+                BITMAPINFOHEADER bih;
+                BYTE *temp_bits;
+                PixelFormat dst_format;
+
+                /* we can't draw a bitmap of this format directly */
+                hdc = CreateCompatibleDC(0);
+                temp_hdc = 1;
+                temp_bitmap = 1;
+
+                bih.biSize = sizeof(BITMAPINFOHEADER);
+                bih.biWidth = bitmap->width;
+                bih.biHeight = -bitmap->height;
+                bih.biPlanes = 1;
+                bih.biBitCount = 32;
+                bih.biCompression = BI_RGB;
+                bih.biSizeImage = 0;
+                bih.biXPelsPerMeter = 0;
+                bih.biYPelsPerMeter = 0;
+                bih.biClrUsed = 0;
+                bih.biClrImportant = 0;
+
+                hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS,
+                    (void**)&temp_bits, NULL, 0);
+
+                if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha))
+                    dst_format = PixelFormat32bppPARGB;
+                else
+                    dst_format = PixelFormat32bppRGB;
 
-        if (temp_hdc)
-        {
-            SelectObject(hdc, old_hbm);
-            DeleteDC(hdc);
-        }
+                convert_pixels(bitmap->width, bitmap->height,
+                    bitmap->width*4, temp_bits, dst_format,
+                    bitmap->stride, bitmap->bits, bitmap->format, bitmap->image.palette_entries);
+            }
+            else
+            {
+                hbitmap = bitmap->hbitmap;
+                hdc = bitmap->hdc;
+                temp_hdc = (hdc == 0);
+            }
+
+            if (temp_hdc)
+            {
+                if (!hdc) hdc = CreateCompatibleDC(0);
+                old_hbm = SelectObject(hdc, hbitmap);
+            }
+
+            if (bitmap->format & (PixelFormatAlpha|PixelFormatPAlpha))
+            {
+                BLENDFUNCTION bf;
+
+                bf.BlendOp = AC_SRC_OVER;
+                bf.BlendFlags = 0;
+                bf.SourceConstantAlpha = 255;
+                bf.AlphaFormat = AC_SRC_ALPHA;
+
+                GdiAlphaBlend(graphics->hdc, pti[0].x, pti[0].y, pti[1].x-pti[0].x, pti[2].y-pti[0].y,
+                    hdc, srcx*dx, srcy*dy, srcwidth*dx, srcheight*dy, bf);
+            }
+            else
+            {
+                StretchBlt(graphics->hdc, pti[0].x, pti[0].y, pti[1].x-pti[0].x, pti[2].y-pti[0].y,
+                    hdc, srcx*dx, srcy*dy, srcwidth*dx, srcheight*dy, SRCCOPY);
+            }
+
+            if (temp_hdc)
+            {
+                SelectObject(hdc, old_hbm);
+                DeleteDC(hdc);
+            }
 
-        if (temp_bitmap)
-            DeleteObject(hbitmap);
+            if (temp_bitmap)
+                DeleteObject(hbitmap);
+        }
     }
     else
     {
@@ -2403,292 +2622,90 @@ GpStatus WINGDIPAPI GdipDrawRectanglesI(GpGraphics *graphics, GpPen *pen,
     return ret;
 }
 
-GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string,
-    INT length, GDIPCONST GpFont *font, GDIPCONST RectF *rect,
-    GDIPCONST GpStringFormat *format, GDIPCONST GpBrush *brush)
+GpStatus WINGDIPAPI GdipFillClosedCurve2(GpGraphics *graphics, GpBrush *brush,
+    GDIPCONST GpPointF *points, INT count, REAL tension, GpFillMode fill)
 {
-    HRGN rgn = NULL;
-    HFONT gdifont;
-    LOGFONTW lfw;
-    TEXTMETRICW textmet;
-    GpPointF pt[3], rectcpy[4];
-    POINT corners[4];
-    WCHAR* stringdup;
-    REAL angle, ang_cos, ang_sin, rel_width, rel_height;
-    INT sum = 0, height = 0, offsety = 0, fit, fitcpy, save_state, i, j, lret, nwidth,
-        nheight, lineend;
-    SIZE size;
-    POINT drawbase;
-    UINT drawflags;
-    RECT drawcoord;
+    GpPath *path;
+    GpStatus stat;
 
-    TRACE("(%p, %s, %i, %p, %s, %p, %p)\n", graphics, debugstr_wn(string, length),
-        length, font, debugstr_rectf(rect), format, brush);
+    TRACE("(%p, %p, %p, %d, %.2f, %d)\n", graphics, brush, points,
+            count, tension, fill);
 
-    if(!graphics || !string || !font || !brush || !rect)
+    if(!graphics || !brush || !points)
         return InvalidParameter;
 
-    if((brush->bt != BrushTypeSolidColor)){
-        FIXME("not implemented for given parameters\n");
-        return NotImplemented;
-    }
-
-    if(format){
-        TRACE("may be ignoring some format flags: attr %x\n", format->attr);
+    if(graphics->busy)
+        return ObjectBusy;
 
-        /* Should be no need to explicitly test for StringAlignmentNear as
-         * that is default behavior if no alignment is passed. */
-        if(format->vertalign != StringAlignmentNear){
-            RectF bounds;
-            GdipMeasureString(graphics, string, length, font, rect, format, &bounds, 0, 0);
+    stat = GdipCreatePath(fill, &path);
+    if(stat != Ok)
+        return stat;
 
-            if(format->vertalign == StringAlignmentCenter)
-                offsety = (rect->Height - bounds.Height) / 2;
-            else if(format->vertalign == StringAlignmentFar)
-                offsety = (rect->Height - bounds.Height);
-        }
+    stat = GdipAddPathClosedCurve2(path, points, count, tension);
+    if(stat != Ok){
+        GdipDeletePath(path);
+        return stat;
     }
 
-    if(length == -1) length = lstrlenW(string);
+    stat = GdipFillPath(graphics, brush, path);
+    if(stat != Ok){
+        GdipDeletePath(path);
+        return stat;
+    }
 
-    stringdup = GdipAlloc(length * sizeof(WCHAR));
-    if(!stringdup) return OutOfMemory;
+    GdipDeletePath(path);
 
-    save_state = SaveDC(graphics->hdc);
-    SetBkMode(graphics->hdc, TRANSPARENT);
-    SetTextColor(graphics->hdc, brush->lb.lbColor);
+    return Ok;
+}
 
-    pt[0].X = 0.0;
-    pt[0].Y = 0.0;
-    pt[1].X = 1.0;
-    pt[1].Y = 0.0;
-    pt[2].X = 0.0;
-    pt[2].Y = 1.0;
-    GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
-    angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
-    ang_cos = cos(angle);
-    ang_sin = sin(angle);
-    rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
-                     (pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
-    rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
-                      (pt[2].X-pt[0].X)*(pt[2].X-pt[0].X));
+GpStatus WINGDIPAPI GdipFillClosedCurve2I(GpGraphics *graphics, GpBrush *brush,
+    GDIPCONST GpPoint *points, INT count, REAL tension, GpFillMode fill)
+{
+    GpPointF *ptf;
+    GpStatus stat;
+    INT i;
 
-    rectcpy[3].X = rectcpy[0].X = rect->X;
-    rectcpy[1].Y = rectcpy[0].Y = rect->Y + offsety;
-    rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width;
-    rectcpy[3].Y = rectcpy[2].Y = rect->Y + offsety + rect->Height;
-    transform_and_round_points(graphics, corners, rectcpy, 4);
+    TRACE("(%p, %p, %p, %d, %.2f, %d)\n", graphics, brush, points,
+            count, tension, fill);
 
-    if (roundr(rect->Width) == 0)
-        nwidth = INT_MAX;
-    else
-        nwidth = roundr(rel_width * rect->Width);
+    if(!points || count <= 0)
+        return InvalidParameter;
 
-    if (roundr(rect->Height) == 0)
-        nheight = INT_MAX;
-    else
-        nheight = roundr(rel_height * rect->Height);
+    ptf = GdipAlloc(sizeof(GpPointF)*count);
+    if(!ptf)
+        return OutOfMemory;
 
-    if (roundr(rect->Width) != 0 && roundr(rect->Height) != 0)
-    {
-        /* FIXME: If only the width or only the height is 0, we should probably still clip */
-        rgn = CreatePolygonRgn(corners, 4, ALTERNATE);
-        SelectClipRgn(graphics->hdc, rgn);
+    for(i = 0;i < count;i++){
+        ptf[i].X = (REAL)points[i].X;
+        ptf[i].Y = (REAL)points[i].Y;
     }
 
-    /* Use gdi to find the font, then perform transformations on it (height,
-     * width, angle). */
-    SelectObject(graphics->hdc, CreateFontIndirectW(&font->lfw));
-    GetTextMetricsW(graphics->hdc, &textmet);
-    lfw = font->lfw;
-
-    lfw.lfHeight = roundr(((REAL)lfw.lfHeight) * rel_height);
-    lfw.lfWidth = roundr(textmet.tmAveCharWidth * rel_width);
+    stat = GdipFillClosedCurve2(graphics, brush, ptf, count, tension, fill);
 
-    lfw.lfEscapement = lfw.lfOrientation = roundr((angle / M_PI) * 1800.0);
+    GdipFree(ptf);
 
-    gdifont = CreateFontIndirectW(&lfw);
-    DeleteObject(SelectObject(graphics->hdc, CreateFontIndirectW(&lfw)));
+    return stat;
+}
 
-    for(i = 0, j = 0; i < length; i++){
-        if(!isprintW(string[i]) && (string[i] != '\n'))
-            continue;
+GpStatus WINGDIPAPI GdipFillEllipse(GpGraphics *graphics, GpBrush *brush, REAL x,
+    REAL y, REAL width, REAL height)
+{
+    INT save_state;
+    GpPointF ptf[2];
+    POINT pti[2];
 
-        stringdup[j] = string[i];
-        j++;
-    }
+    TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f)\n", graphics, brush, x, y, width, height);
 
-    length = j;
+    if(!graphics || !brush)
+        return InvalidParameter;
 
-    if (!format || format->align == StringAlignmentNear)
-    {
-        drawbase.x = corners[0].x;
-        drawbase.y = corners[0].y;
-        drawflags = DT_NOCLIP | DT_EXPANDTABS;
-    }
-    else if (format->align == StringAlignmentCenter)
-    {
-        drawbase.x = (corners[0].x + corners[1].x)/2;
-        drawbase.y = (corners[0].y + corners[1].y)/2;
-        drawflags = DT_NOCLIP | DT_EXPANDTABS | DT_CENTER;
-    }
-    else /* (format->align == StringAlignmentFar) */
-    {
-        drawbase.x = corners[1].x;
-        drawbase.y = corners[1].y;
-        drawflags = DT_NOCLIP | DT_EXPANDTABS | DT_RIGHT;
-    }
+    if(graphics->busy)
+        return ObjectBusy;
 
-    while(sum < length){
-        drawcoord.left = drawcoord.right = drawbase.x + roundr(ang_sin * (REAL) height);
-        drawcoord.top = drawcoord.bottom = drawbase.y + roundr(ang_cos * (REAL) height);
-
-        GetTextExtentExPointW(graphics->hdc, stringdup + sum, length - sum,
-                              nwidth, &fit, NULL, &size);
-        fitcpy = fit;
-
-        if(fit == 0){
-            DrawTextW(graphics->hdc, stringdup + sum, 1, &drawcoord, drawflags);
-            break;
-        }
-
-        for(lret = 0; lret < fit; lret++)
-            if(*(stringdup + sum + lret) == '\n')
-                break;
-
-        /* Line break code (may look strange, but it imitates windows). */
-        if(lret < fit)
-            lineend = fit = lret;    /* this is not an off-by-one error */
-        else if(fit < (length - sum)){
-            if(*(stringdup + sum + fit) == ' ')
-                while(*(stringdup + sum + fit) == ' ')
-                    fit++;
-            else
-                while(*(stringdup + sum + fit - 1) != ' '){
-                    fit--;
-
-                    if(*(stringdup + sum + fit) == '\t')
-                        break;
-
-                    if(fit == 0){
-                        fit = fitcpy;
-                        break;
-                    }
-                }
-            lineend = fit;
-            while(*(stringdup + sum + lineend - 1) == ' ' ||
-                  *(stringdup + sum + lineend - 1) == '\t')
-                lineend--;
-        }
-        else
-            lineend = fit;
-        DrawTextW(graphics->hdc, stringdup + sum, min(length - sum, lineend),
-                  &drawcoord, drawflags);
-
-        sum += fit + (lret < fitcpy ? 1 : 0);
-        height += size.cy;
-
-        if(height > nheight)
-            break;
-
-        /* Stop if this was a linewrap (but not if it was a linebreak). */
-        if((lret == fitcpy) && format && (format->attr & StringFormatFlagsNoWrap))
-            break;
-    }
-
-    GdipFree(stringdup);
-    DeleteObject(rgn);
-    DeleteObject(gdifont);
-
-    RestoreDC(graphics->hdc, save_state);
-
-    return Ok;
-}
-
-GpStatus WINGDIPAPI GdipFillClosedCurve2(GpGraphics *graphics, GpBrush *brush,
-    GDIPCONST GpPointF *points, INT count, REAL tension, GpFillMode fill)
-{
-    GpPath *path;
-    GpStatus stat;
-
-    TRACE("(%p, %p, %p, %d, %.2f, %d)\n", graphics, brush, points,
-            count, tension, fill);
-
-    if(!graphics || !brush || !points)
-        return InvalidParameter;
-
-    if(graphics->busy)
-        return ObjectBusy;
-
-    stat = GdipCreatePath(fill, &path);
-    if(stat != Ok)
-        return stat;
-
-    stat = GdipAddPathClosedCurve2(path, points, count, tension);
-    if(stat != Ok){
-        GdipDeletePath(path);
-        return stat;
-    }
-
-    stat = GdipFillPath(graphics, brush, path);
-    if(stat != Ok){
-        GdipDeletePath(path);
-        return stat;
-    }
-
-    GdipDeletePath(path);
-
-    return Ok;
-}
-
-GpStatus WINGDIPAPI GdipFillClosedCurve2I(GpGraphics *graphics, GpBrush *brush,
-    GDIPCONST GpPoint *points, INT count, REAL tension, GpFillMode fill)
-{
-    GpPointF *ptf;
-    GpStatus stat;
-    INT i;
-
-    TRACE("(%p, %p, %p, %d, %.2f, %d)\n", graphics, brush, points,
-            count, tension, fill);
-
-    if(!points || count <= 0)
-        return InvalidParameter;
-
-    ptf = GdipAlloc(sizeof(GpPointF)*count);
-    if(!ptf)
-        return OutOfMemory;
-
-    for(i = 0;i < count;i++){
-        ptf[i].X = (REAL)points[i].X;
-        ptf[i].Y = (REAL)points[i].Y;
-    }
-
-    stat = GdipFillClosedCurve2(graphics, brush, ptf, count, tension, fill);
-
-    GdipFree(ptf);
-
-    return stat;
-}
-
-GpStatus WINGDIPAPI GdipFillEllipse(GpGraphics *graphics, GpBrush *brush, REAL x,
-    REAL y, REAL width, REAL height)
-{
-    INT save_state;
-    GpPointF ptf[2];
-    POINT pti[2];
-
-    TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f)\n", graphics, brush, x, y, width, height);
-
-    if(!graphics || !brush)
-        return InvalidParameter;
-
-    if(graphics->busy)
-        return ObjectBusy;
-
-    ptf[0].X = x;
-    ptf[0].Y = y;
-    ptf[1].X = x + width;
-    ptf[1].Y = y + height;
+    ptf[0].X = x;
+    ptf[0].Y = y;
+    ptf[1].X = x + width;
+    ptf[1].Y = y + height;
 
     save_state = SaveDC(graphics->hdc);
     EndPath(graphics->hdc);
@@ -3074,8 +3091,6 @@ GpStatus WINGDIPAPI GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
 
 GpStatus WINGDIPAPI GdipFlush(GpGraphics *graphics, GpFlushIntention intention)
 {
-    static int calls;
-
     TRACE("(%p,%u)\n", graphics, intention);
 
     if(!graphics)
@@ -3084,10 +3099,12 @@ GpStatus WINGDIPAPI GdipFlush(GpGraphics *graphics, GpFlushIntention intention)
     if(graphics->busy)
         return ObjectBusy;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
+    /* We have no internal operation queue, so there's no need to clear it. */
 
-    return NotImplemented;
+    if (graphics->hdc)
+        GdiFlush();
+
+    return Ok;
 }
 
 /*****************************************************************************
@@ -3465,61 +3482,37 @@ GpStatus WINGDIPAPI GdipIsVisibleRectI(GpGraphics *graphics, INT x, INT y, INT w
     return GdipIsVisibleRect(graphics, (REAL)x, (REAL)y, (REAL)width, (REAL)height, result);
 }
 
-GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
-        GDIPCONST WCHAR* string, INT length, GDIPCONST GpFont* font,
-        GDIPCONST RectF* layoutRect, GDIPCONST GpStringFormat *stringFormat,
-        INT regionCount, GpRegion** regions)
-{
-    FIXME("stub: %p %s %d %p %p %p %d %p\n", graphics, debugstr_w(string),
-            length, font, layoutRect, stringFormat, regionCount, regions);
-
-    if (!(graphics && string && font && layoutRect && stringFormat && regions))
-        return InvalidParameter;
+typedef GpStatus (*gdip_format_string_callback)(GpGraphics *graphics,
+    GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
+    GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
+    INT lineno, const RectF *bounds, void *user_data);
 
-    return NotImplemented;
-}
-
-/* Find the smallest rectangle that bounds the text when it is printed in rect
- * according to the format options listed in format. If rect has 0 width and
- * height, then just find the smallest rectangle that bounds the text when it's
- * printed at location (rect->X, rect-Y). */
-GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
+static GpStatus gdip_format_string(GpGraphics *graphics,
     GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font,
-    GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format, RectF *bounds,
-    INT *codepointsfitted, INT *linesfilled)
+    GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
+    gdip_format_string_callback callback, void *user_data)
 {
-    HFONT oldfont;
     WCHAR* stringdup;
-    INT sum = 0, height = 0, fit, fitcpy, max_width = 0, i, j, lret, nwidth,
-        nheight, lineend;
+    INT sum = 0, height = 0, fit, fitcpy, i, j, lret, nwidth,
+        nheight, lineend, lineno = 0;
+    RectF bounds;
+    StringAlignment halign;
+    GpStatus stat = Ok;
     SIZE size;
 
-    TRACE("(%p, %s, %i, %p, %s, %p, %p, %p, %p)\n", graphics,
-        debugstr_wn(string, length), length, font, debugstr_rectf(rect), format,
-        bounds, codepointsfitted, linesfilled);
-
-    if(!graphics || !string || !font || !rect)
-        return InvalidParameter;
-
-    if(linesfilled) *linesfilled = 0;
-    if(codepointsfitted) *codepointsfitted = 0;
-
-    if(format)
-        TRACE("may be ignoring some format flags: attr %x\n", format->attr);
-
     if(length == -1) length = lstrlenW(string);
 
     stringdup = GdipAlloc((length + 1) * sizeof(WCHAR));
     if(!stringdup) return OutOfMemory;
 
-    oldfont = SelectObject(graphics->hdc, CreateFontIndirectW(&font->lfw));
     nwidth = roundr(rect->Width);
     nheight = roundr(rect->Height);
 
-    if((nwidth == 0) && (nheight == 0))
-        nwidth = nheight = INT_MAX;
+    if (nwidth == 0) nwidth = INT_MAX;
+    if (nheight == 0) nheight = INT_MAX;
 
     for(i = 0, j = 0; i < length; i++){
+        /* FIXME: This makes the indexes passed to callback inaccurate. */
         if(!isprintW(string[i]) && (string[i] != '\n'))
             continue;
 
@@ -3527,9 +3520,11 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
         j++;
     }
 
-    stringdup[j] = 0;
     length = j;
 
+    if (format) halign = format->align;
+    else halign = StringAlignmentNear;
+
     while(sum < length){
         GetTextExtentExPointW(graphics->hdc, stringdup + sum, length - sum,
                               nwidth, &fit, NULL, &size);
@@ -3572,12 +3567,38 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
         GetTextExtentExPointW(graphics->hdc, stringdup + sum, lineend,
                               nwidth, &j, NULL, &size);
 
-        sum += fit + (lret < fitcpy ? 1 : 0);
-        if(codepointsfitted) *codepointsfitted = sum;
+        bounds.Width = size.cx;
+
+        if(height + size.cy > nheight)
+            bounds.Height = nheight - (height + size.cy);
+        else
+            bounds.Height = size.cy;
+
+        bounds.Y = rect->Y + height;
 
+        switch (halign)
+        {
+        case StringAlignmentNear:
+        default:
+            bounds.X = rect->X;
+            break;
+        case StringAlignmentCenter:
+            bounds.X = rect->X + (rect->Width/2) - (bounds.Width/2);
+            break;
+        case StringAlignmentFar:
+            bounds.X = rect->X + rect->Width - bounds.Width;
+            break;
+        }
+
+        stat = callback(graphics, stringdup, sum, lineend,
+            font, rect, format, lineno, &bounds, user_data);
+
+        if (stat != Ok)
+            break;
+
+        sum += fit + (lret < fitcpy ? 1 : 0);
         height += size.cy;
-        if(linesfilled) *linesfilled += size.cy;
-        max_width = max(max_width, size.cx);
+        lineno++;
 
         if(height > nheight)
             break;
@@ -3587,17 +3608,311 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
             break;
     }
 
+    GdipFree(stringdup);
+
+    return stat;
+}
+
+struct measure_ranges_args {
+    GpRegion **regions;
+};
+
+GpStatus measure_ranges_callback(GpGraphics *graphics,
+    GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
+    GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
+    INT lineno, const RectF *bounds, void *user_data)
+{
+    int i;
+    GpStatus stat = Ok;
+    struct measure_ranges_args *args = user_data;
+
+    for (i=0; i<format->range_count; i++)
+    {
+        INT range_start = max(index, format->character_ranges[i].First);
+        INT range_end = min(index+length, format->character_ranges[i].First+format->character_ranges[i].Length);
+        if (range_start < range_end)
+        {
+            GpRectF range_rect;
+            SIZE range_size;
+
+            range_rect.Y = bounds->Y;
+            range_rect.Height = bounds->Height;
+
+            GetTextExtentExPointW(graphics->hdc, string + index, range_start - index,
+                                  INT_MAX, NULL, NULL, &range_size);
+            range_rect.X = bounds->X + range_size.cx;
+
+            GetTextExtentExPointW(graphics->hdc, string + index, range_end - index,
+                                  INT_MAX, NULL, NULL, &range_size);
+            range_rect.Width = (bounds->X + range_size.cx) - range_rect.X;
+
+            stat = GdipCombineRegionRect(args->regions[i], &range_rect, CombineModeUnion);
+            if (stat != Ok)
+                break;
+        }
+    }
+
+    return stat;
+}
+
+GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
+        GDIPCONST WCHAR* string, INT length, GDIPCONST GpFont* font,
+        GDIPCONST RectF* layoutRect, GDIPCONST GpStringFormat *stringFormat,
+        INT regionCount, GpRegion** regions)
+{
+    GpStatus stat;
+    int i;
+    HFONT oldfont;
+    struct measure_ranges_args args;
+
+    TRACE("(%p %s %d %p %s %p %d %p)\n", graphics, debugstr_w(string),
+            length, font, debugstr_rectf(layoutRect), stringFormat, regionCount, regions);
+
+    if (!(graphics && string && font && layoutRect && stringFormat && regions))
+        return InvalidParameter;
+
+    if (regionCount < stringFormat->range_count)
+        return InvalidParameter;
+
+    if (stringFormat->attr)
+        TRACE("may be ignoring some format flags: attr %x\n", stringFormat->attr);
+
+    oldfont = SelectObject(graphics->hdc, CreateFontIndirectW(&font->lfw));
+
+    for (i=0; i<stringFormat->range_count; i++)
+    {
+        stat = GdipSetEmpty(regions[i]);
+        if (stat != Ok)
+            return stat;
+    }
+
+    args.regions = regions;
+
+    stat = gdip_format_string(graphics, string, length, font, layoutRect, stringFormat,
+        measure_ranges_callback, &args);
+
+    DeleteObject(SelectObject(graphics->hdc, oldfont));
+
+    return stat;
+}
+
+struct measure_string_args {
+    RectF *bounds;
+    INT *codepointsfitted;
+    INT *linesfilled;
+};
+
+static GpStatus measure_string_callback(GpGraphics *graphics,
+    GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
+    GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
+    INT lineno, const RectF *bounds, void *user_data)
+{
+    struct measure_string_args *args = user_data;
+
+    if (bounds->Width > args->bounds->Width)
+        args->bounds->Width = bounds->Width;
+
+    if (bounds->Height + bounds->Y > args->bounds->Height + args->bounds->Y)
+        args->bounds->Height = bounds->Height + bounds->Y - args->bounds->Y;
+
+    if (args->codepointsfitted)
+        *args->codepointsfitted = index + length;
+
+    if (args->linesfilled)
+        (*args->linesfilled)++;
+
+    return Ok;
+}
+
+/* Find the smallest rectangle that bounds the text when it is printed in rect
+ * according to the format options listed in format. If rect has 0 width and
+ * height, then just find the smallest rectangle that bounds the text when it's
+ * printed at location (rect->X, rect-Y). */
+GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
+    GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font,
+    GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format, RectF *bounds,
+    INT *codepointsfitted, INT *linesfilled)
+{
+    HFONT oldfont;
+    struct measure_string_args args;
+
+    TRACE("(%p, %s, %i, %p, %s, %p, %p, %p, %p)\n", graphics,
+        debugstr_wn(string, length), length, font, debugstr_rectf(rect), format,
+        bounds, codepointsfitted, linesfilled);
+
+    if(!graphics || !string || !font || !rect || !bounds)
+        return InvalidParameter;
+
+    if(linesfilled) *linesfilled = 0;
+    if(codepointsfitted) *codepointsfitted = 0;
+
+    if(format)
+        TRACE("may be ignoring some format flags: attr %x\n", format->attr);
+
+    oldfont = SelectObject(graphics->hdc, CreateFontIndirectW(&font->lfw));
+
     bounds->X = rect->X;
     bounds->Y = rect->Y;
-    bounds->Width = (REAL)max_width;
-    bounds->Height = (REAL) min(height, nheight);
+    bounds->Width = 0.0;
+    bounds->Height = 0.0;
+
+    args.bounds = bounds;
+    args.codepointsfitted = codepointsfitted;
+    args.linesfilled = linesfilled;
+
+    gdip_format_string(graphics, string, length, font, rect, format,
+        measure_string_callback, &args);
 
-    GdipFree(stringdup);
     DeleteObject(SelectObject(graphics->hdc, oldfont));
 
     return Ok;
 }
 
+struct draw_string_args {
+    POINT drawbase;
+    UINT drawflags;
+    REAL ang_cos, ang_sin;
+};
+
+static GpStatus draw_string_callback(GpGraphics *graphics,
+    GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
+    GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
+    INT lineno, const RectF *bounds, void *user_data)
+{
+    struct draw_string_args *args = user_data;
+    RECT drawcoord;
+
+    drawcoord.left = drawcoord.right = args->drawbase.x + roundr(args->ang_sin * bounds->Y);
+    drawcoord.top = drawcoord.bottom = args->drawbase.y + roundr(args->ang_cos * bounds->Y);
+
+    DrawTextW(graphics->hdc, string + index, length, &drawcoord, args->drawflags);
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string,
+    INT length, GDIPCONST GpFont *font, GDIPCONST RectF *rect,
+    GDIPCONST GpStringFormat *format, GDIPCONST GpBrush *brush)
+{
+    HRGN rgn = NULL;
+    HFONT gdifont;
+    LOGFONTW lfw;
+    TEXTMETRICW textmet;
+    GpPointF pt[3], rectcpy[4];
+    POINT corners[4];
+    REAL angle, rel_width, rel_height;
+    INT offsety = 0, save_state;
+    struct draw_string_args args;
+    RectF scaled_rect;
+
+    TRACE("(%p, %s, %i, %p, %s, %p, %p)\n", graphics, debugstr_wn(string, length),
+        length, font, debugstr_rectf(rect), format, brush);
+
+    if(!graphics || !string || !font || !brush || !rect)
+        return InvalidParameter;
+
+    if((brush->bt != BrushTypeSolidColor)){
+        FIXME("not implemented for given parameters\n");
+        return NotImplemented;
+    }
+
+    if(format){
+        TRACE("may be ignoring some format flags: attr %x\n", format->attr);
+
+        /* Should be no need to explicitly test for StringAlignmentNear as
+         * that is default behavior if no alignment is passed. */
+        if(format->vertalign != StringAlignmentNear){
+            RectF bounds;
+            GdipMeasureString(graphics, string, length, font, rect, format, &bounds, 0, 0);
+
+            if(format->vertalign == StringAlignmentCenter)
+                offsety = (rect->Height - bounds.Height) / 2;
+            else if(format->vertalign == StringAlignmentFar)
+                offsety = (rect->Height - bounds.Height);
+        }
+    }
+
+    save_state = SaveDC(graphics->hdc);
+    SetBkMode(graphics->hdc, TRANSPARENT);
+    SetTextColor(graphics->hdc, brush->lb.lbColor);
+
+    pt[0].X = 0.0;
+    pt[0].Y = 0.0;
+    pt[1].X = 1.0;
+    pt[1].Y = 0.0;
+    pt[2].X = 0.0;
+    pt[2].Y = 1.0;
+    GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
+    angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
+    args.ang_cos = cos(angle);
+    args.ang_sin = sin(angle);
+    rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
+                     (pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
+    rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
+                      (pt[2].X-pt[0].X)*(pt[2].X-pt[0].X));
+
+    rectcpy[3].X = rectcpy[0].X = rect->X;
+    rectcpy[1].Y = rectcpy[0].Y = rect->Y + offsety;
+    rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width;
+    rectcpy[3].Y = rectcpy[2].Y = rect->Y + offsety + rect->Height;
+    transform_and_round_points(graphics, corners, rectcpy, 4);
+
+    scaled_rect.X = 0.0;
+    scaled_rect.Y = 0.0;
+    scaled_rect.Width = rel_width * rect->Width;
+    scaled_rect.Height = rel_height * rect->Height;
+
+    if (roundr(scaled_rect.Width) != 0 && roundr(scaled_rect.Height) != 0)
+    {
+        /* FIXME: If only the width or only the height is 0, we should probably still clip */
+        rgn = CreatePolygonRgn(corners, 4, ALTERNATE);
+        SelectClipRgn(graphics->hdc, rgn);
+    }
+
+    /* Use gdi to find the font, then perform transformations on it (height,
+     * width, angle). */
+    SelectObject(graphics->hdc, CreateFontIndirectW(&font->lfw));
+    GetTextMetricsW(graphics->hdc, &textmet);
+    lfw = font->lfw;
+
+    lfw.lfHeight = roundr(((REAL)lfw.lfHeight) * rel_height);
+    lfw.lfWidth = roundr(textmet.tmAveCharWidth * rel_width);
+
+    lfw.lfEscapement = lfw.lfOrientation = roundr((angle / M_PI) * 1800.0);
+
+    gdifont = CreateFontIndirectW(&lfw);
+    DeleteObject(SelectObject(graphics->hdc, CreateFontIndirectW(&lfw)));
+
+    if (!format || format->align == StringAlignmentNear)
+    {
+        args.drawbase.x = corners[0].x;
+        args.drawbase.y = corners[0].y;
+        args.drawflags = DT_NOCLIP | DT_EXPANDTABS;
+    }
+    else if (format->align == StringAlignmentCenter)
+    {
+        args.drawbase.x = (corners[0].x + corners[1].x)/2;
+        args.drawbase.y = (corners[0].y + corners[1].y)/2;
+        args.drawflags = DT_NOCLIP | DT_EXPANDTABS | DT_CENTER;
+    }
+    else /* (format->align == StringAlignmentFar) */
+    {
+        args.drawbase.x = corners[1].x;
+        args.drawbase.y = corners[1].y;
+        args.drawflags = DT_NOCLIP | DT_EXPANDTABS | DT_RIGHT;
+    }
+
+    gdip_format_string(graphics, string, length, font, &scaled_rect, format,
+        draw_string_callback, &args);
+
+    DeleteObject(rgn);
+    DeleteObject(gdifont);
+
+    RestoreDC(graphics->hdc, save_state);
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipResetClip(GpGraphics *graphics)
 {
     TRACE("(%p)\n", graphics);
@@ -4300,7 +4615,12 @@ GpStatus WINGDIPAPI GdipTransformPointsI(GpGraphics *graphics, GpCoordinateSpace
 
 HPALETTE WINGDIPAPI GdipCreateHalftonePalette(void)
 {
-    FIXME("\n");
+    static int calls;
+
+    TRACE("\n");
+
+    if (!calls++)
+      FIXME("stub\n");
 
     return NULL;
 }
index 58f3c65..0a73dcf 100644 (file)
@@ -122,7 +122,7 @@ static inline void getpixel_16bppGrayScale(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
 static inline void getpixel_16bppRGB555(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
     const BYTE *row, UINT x)
 {
-    WORD pixel = *((WORD*)(row)+x);
+    WORD pixel = *((const WORD*)(row)+x);
     *r = (pixel>>7&0xf8)|(pixel>>12&0x7);
     *g = (pixel>>2&0xf8)|(pixel>>6&0x7);
     *b = (pixel<<3&0xf8)|(pixel>>2&0x7);
@@ -132,7 +132,7 @@ static inline void getpixel_16bppRGB555(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
 static inline void getpixel_16bppRGB565(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
     const BYTE *row, UINT x)
 {
-    WORD pixel = *((WORD*)(row)+x);
+    WORD pixel = *((const WORD*)(row)+x);
     *r = (pixel>>8&0xf8)|(pixel>>13&0x7);
     *g = (pixel>>3&0xfc)|(pixel>>9&0x3);
     *b = (pixel<<3&0xf8)|(pixel>>2&0x7);
@@ -142,7 +142,7 @@ static inline void getpixel_16bppRGB565(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
 static inline void getpixel_16bppARGB1555(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
     const BYTE *row, UINT x)
 {
-    WORD pixel = *((WORD*)(row)+x);
+    WORD pixel = *((const WORD*)(row)+x);
     *r = (pixel>>7&0xf8)|(pixel>>12&0x7);
     *g = (pixel>>2&0xf8)|(pixel>>6&0x7);
     *b = (pixel<<3&0xf8)|(pixel>>2&0x7);
@@ -1831,6 +1831,37 @@ GpStatus WINGDIPAPI GdipEmfToWmfBits(HENHMETAFILE hemf, UINT cbData16,
     return NotImplemented;
 }
 
+/* Internal utility function: Replace the image data of dst with that of src,
+ * and free src. */
+static void move_bitmap(GpBitmap *dst, GpBitmap *src, BOOL clobber_palette)
+{
+    GdipFree(dst->bitmapbits);
+    DeleteDC(dst->hdc);
+    DeleteObject(dst->hbitmap);
+
+    if (clobber_palette)
+    {
+        GdipFree(dst->image.palette_entries);
+        dst->image.palette_flags = src->image.palette_flags;
+        dst->image.palette_count = src->image.palette_count;
+        dst->image.palette_entries = src->image.palette_entries;
+    }
+    else
+        GdipFree(src->image.palette_entries);
+
+    dst->image.xres = src->image.xres;
+    dst->image.yres = src->image.yres;
+    dst->width = src->width;
+    dst->height = src->height;
+    dst->format = src->format;
+    dst->hbitmap = src->hbitmap;
+    dst->hdc = src->hdc;
+    dst->bits = src->bits;
+    dst->stride = src->stride;
+
+    GdipFree(src);
+}
+
 GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
 {
     TRACE("%p\n", image);
@@ -1946,6 +1977,7 @@ GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image,
     GpGraphics **graphics)
 {
     HDC hdc;
+    GpStatus stat;
 
     TRACE("%p %p\n", image, graphics);
 
@@ -1965,7 +1997,12 @@ GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image,
         ((GpBitmap*)image)->hdc = hdc;
     }
 
-    return GdipCreateFromHDC(hdc, graphics);
+    stat = GdipCreateFromHDC(hdc, graphics);
+
+    if (stat == Ok)
+        (*graphics)->image = image;
+
+    return stat;
 }
 
 GpStatus WINGDIPAPI GdipGetImageHeight(GpImage *image, UINT *height)
@@ -2459,6 +2496,11 @@ static GpStatus decode_image_gif(IStream* stream, REFCLSID clsid, GpImage **imag
     return decode_image_wic(stream, &CLSID_WICGifDecoder, image);
 }
 
+static GpStatus decode_image_tiff(IStream* stream, REFCLSID clsid, GpImage **image)
+{
+    return decode_image_wic(stream, &CLSID_WICTiffDecoder, image);
+}
+
 static GpStatus decode_image_olepicture_metafile(IStream* stream, REFCLSID clsid, GpImage **image)
 {
     IPicture *pic;
@@ -2505,6 +2547,7 @@ typedef enum {
     BMP,
     JPEG,
     GIF,
+    TIFF,
     EMF,
     WMF,
     PNG,
@@ -2517,10 +2560,11 @@ static const struct image_codec codecs[NUM_CODECS];
 static GpStatus get_decoder_info(IStream* stream, const struct image_codec **result)
 {
     BYTE signature[8];
+    const BYTE *pattern, *mask;
     LARGE_INTEGER seek;
     HRESULT hr;
     UINT bytesread;
-    int i, j;
+    int i, j, sig;
 
     /* seek to the start of the stream */
     seek.QuadPart = 0;
@@ -2528,7 +2572,7 @@ static GpStatus get_decoder_info(IStream* stream, const struct image_codec **res
     if (FAILED(hr)) return hresult_to_status(hr);
 
     /* read the first 8 bytes */
-    /* FIXME: This assumes all codecs have one signature <= 8 bytes in length */
+    /* FIXME: This assumes all codecs have signatures <= 8 bytes in length */
     hr = IStream_Read(stream, signature, 8, &bytesread);
     if (FAILED(hr)) return hresult_to_status(hr);
     if (hr == S_FALSE || bytesread == 0) return GenericError;
@@ -2537,13 +2581,18 @@ static GpStatus get_decoder_info(IStream* stream, const struct image_codec **res
         if ((codecs[i].info.Flags & ImageCodecFlagsDecoder) &&
             bytesread >= codecs[i].info.SigSize)
         {
-            for (j=0; j<codecs[i].info.SigSize; j++)
-                if ((signature[j] & codecs[i].info.SigMask[j]) != codecs[i].info.SigPattern[j])
-                    break;
-            if (j == codecs[i].info.SigSize)
+            for (sig=0; sig<codecs[i].info.SigCount; sig++)
             {
-                *result = &codecs[i];
-                return Ok;
+                pattern = &codecs[i].info.SigPattern[codecs[i].info.SigSize*sig];
+                mask = &codecs[i].info.SigMask[codecs[i].info.SigSize*sig];
+                for (j=0; j<codecs[i].info.SigSize; j++)
+                    if ((signature[j] & mask[j]) != pattern[j])
+                        break;
+                if (j == codecs[i].info.SigSize)
+                {
+                    *result = &codecs[i];
+                    return Ok;
+                }
             }
         }
     }
@@ -2900,6 +2949,13 @@ static const WCHAR gif_format[] = {'G','I','F',0};
 static const BYTE gif_sig_pattern[4] = "GIF8";
 static const BYTE gif_sig_mask[] = { 0xFF, 0xFF, 0xFF, 0xFF };
 
+static const WCHAR tiff_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'T','I','F','F', 0};
+static const WCHAR tiff_extension[] = {'*','.','T','I','F','F',';','*','.','T','I','F',0};
+static const WCHAR tiff_mimetype[] = {'i','m','a','g','e','/','t','i','f','f', 0};
+static const WCHAR tiff_format[] = {'T','I','F','F',0};
+static const BYTE tiff_sig_pattern[] = {0x49,0x49,42,0,0x4d,0x4d,0,42};
+static const BYTE tiff_sig_mask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
 static const WCHAR emf_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'E','M','F', 0};
 static const WCHAR emf_extension[] = {'*','.','E','M','F',0};
 static const WCHAR emf_mimetype[] = {'i','m','a','g','e','/','x','-','e','m','f', 0};
@@ -2986,6 +3042,25 @@ static const struct image_codec codecs[NUM_CODECS] = {
         NULL,
         decode_image_gif
     },
+    {
+        { /* TIFF */
+            /* Clsid */              { 0x557cf405, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } },
+            /* FormatID */           { 0xb96b3cb1U, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} },
+            /* CodecName */          tiff_codecname,
+            /* DllName */            NULL,
+            /* FormatDescription */  tiff_format,
+            /* FilenameExtension */  tiff_extension,
+            /* MimeType */           tiff_mimetype,
+            /* Flags */              ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
+            /* Version */            1,
+            /* SigCount */           2,
+            /* SigSize */            4,
+            /* SigPattern */         tiff_sig_pattern,
+            /* SigMask */            tiff_sig_mask,
+        },
+        NULL,
+        decode_image_tiff
+    },
     {
         { /* EMF */
             /* Clsid */              { 0x557cf403, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } },
@@ -3394,6 +3469,112 @@ GpStatus WINGDIPAPI GdipGetImageThumbnail(GpImage *image, UINT width, UINT heigh
  */
 GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type)
 {
-    FIXME("(%p %u) stub\n", image, type);
-    return NotImplemented;
+    GpBitmap *new_bitmap;
+    GpBitmap *bitmap;
+    int bpp, bytesperpixel;
+    int rotate_90, flip_x, flip_y;
+    int src_x_offset, src_y_offset;
+    LPBYTE src_origin;
+    UINT x, y, width, height;
+    BitmapData src_lock, dst_lock;
+    GpStatus stat;
+
+    TRACE("(%p, %u)\n", image, type);
+
+    rotate_90 = type&1;
+    flip_x = (type&6) == 2 || (type&6) == 4;
+    flip_y = (type&3) == 1 || (type&3) == 2;
+
+    if (image->type != ImageTypeBitmap)
+    {
+        FIXME("Not implemented for type %i\n", image->type);
+        return NotImplemented;
+    }
+
+    bitmap = (GpBitmap*)image;
+    bpp = PIXELFORMATBPP(bitmap->format);
+
+    if (bpp < 8)
+    {
+        FIXME("Not implemented for %i bit images\n", bpp);
+        return NotImplemented;
+    }
+
+    if (rotate_90)
+    {
+        width = bitmap->height;
+        height = bitmap->width;
+    }
+    else
+    {
+        width = bitmap->width;
+        height = bitmap->height;
+    }
+
+    bytesperpixel = bpp/8;
+
+    stat = GdipCreateBitmapFromScan0(width, height, 0, bitmap->format, NULL, &new_bitmap);
+
+    if (stat != Ok)
+        return stat;
+
+    stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, bitmap->format, &src_lock);
+
+    if (stat == Ok)
+    {
+        stat = GdipBitmapLockBits(new_bitmap, NULL, ImageLockModeWrite, bitmap->format, &dst_lock);
+
+        if (stat == Ok)
+        {
+            LPBYTE src_row, src_pixel;
+            LPBYTE dst_row, dst_pixel;
+
+            src_origin = src_lock.Scan0;
+            if (flip_x) src_origin += bytesperpixel * (bitmap->width - 1);
+            if (flip_y) src_origin += src_lock.Stride * (bitmap->height - 1);
+
+            if (rotate_90)
+            {
+                if (flip_y) src_x_offset = -src_lock.Stride;
+                else src_x_offset = src_lock.Stride;
+                if (flip_x) src_y_offset = -bytesperpixel;
+                else src_y_offset = bytesperpixel;
+            }
+            else
+            {
+                if (flip_x) src_x_offset = -bytesperpixel;
+                else src_x_offset = bytesperpixel;
+                if (flip_y) src_y_offset = -src_lock.Stride;
+                else src_y_offset = src_lock.Stride;
+            }
+
+            src_row = src_origin;
+            dst_row = dst_lock.Scan0;
+            for (y=0; y<height; y++)
+            {
+                src_pixel = src_row;
+                dst_pixel = dst_row;
+                for (x=0; x<width; x++)
+                {
+                    /* FIXME: This could probably be faster without memcpy. */
+                    memcpy(dst_pixel, src_pixel, bytesperpixel);
+                    dst_pixel += bytesperpixel;
+                    src_pixel += src_x_offset;
+                }
+                src_row += src_y_offset;
+                dst_row += dst_lock.Stride;
+            }
+
+            GdipBitmapUnlockBits(new_bitmap, &dst_lock);
+        }
+
+        GdipBitmapUnlockBits(bitmap, &src_lock);
+    }
+
+    if (stat == Ok)
+        move_bitmap(bitmap, new_bitmap, FALSE);
+    else
+        GdipDisposeImage((GpImage*)new_bitmap);
+
+    return stat;
 }
index 99f7130..9ab66de 100644 (file)
@@ -302,7 +302,7 @@ int WINAPI doWinMain(HINSTANCE hInstance, LPSTR szCmdLine)
         }
         else
         {
-            FIXME("Unhandled HTML Help command line parameter! (%.*s)\n", space-szCmdLine, szCmdLine);
+            FIXME("Unhandled HTML Help command line parameter! (%.*s)\n", (int)(space-szCmdLine), szCmdLine);
             return 0;
         }
     }
index 6d37147..97b482e 100644 (file)
@@ -268,7 +268,7 @@ static HRESULT WINAPI MimeInternat_FindCharset(IMimeInternational *iface, LPCSTR
 
         if(SUCCEEDED(hr))
             *phCharset = add_charset(&This->charsets, &mlang_info,
-                                     (HCHARSET)InterlockedIncrement(&This->next_charset_handle));
+                                     UlongToHandle(InterlockedIncrement(&This->next_charset_handle)));
     }
 
     LeaveCriticalSection(&This->cs);
index 992949a..f297c29 100644 (file)
@@ -1419,7 +1419,7 @@ static HRESULT create_sub_stream(IStream *stream, ULARGE_INTEGER start, ULARGE_I
 typedef struct body_t
 {
     struct list entry;
-    HBODY hbody;
+    DWORD index;
     IMimeBody *mime_body;
 
     struct body_t *parent;
@@ -1434,7 +1434,7 @@ typedef struct MimeMessage
     IStream *stream;
 
     struct list body_tree;
-    HBODY next_hbody;
+    DWORD next_index;
 } MimeMessage;
 
 static HRESULT WINAPI MimeMessage_QueryInterface(IMimeMessage *iface, REFIID riid, void **ppv)
@@ -1512,13 +1512,13 @@ static HRESULT WINAPI MimeMessage_IsDirty(
     return E_NOTIMPL;
 }
 
-static body_t *new_body_entry(IMimeBody *mime_body, HBODY hbody, body_t *parent)
+static body_t *new_body_entry(IMimeBody *mime_body, DWORD index, body_t *parent)
 {
     body_t *body = HeapAlloc(GetProcessHeap(), 0, sizeof(*body));
     if(body)
     {
         body->mime_body = mime_body;
-        body->hbody = hbody;
+        body->index = index;
         list_init(&body->children);
         body->parent = parent;
     }
@@ -1630,8 +1630,7 @@ static body_t *create_sub_body(MimeMessage *msg, IStream *pStm, BODYOFFSETS *off
     offset->cbBodyStart = cur.u.LowPart + offset->cbHeaderStart;
     if(parent) MimeBody_set_offsets(impl_from_IMimeBody(mime_body), offset);
     IMimeBody_SetData(mime_body, IET_BINARY, NULL, NULL, &IID_IStream, pStm);
-    body = new_body_entry(mime_body, msg->next_hbody, parent);
-    msg->next_hbody = (HBODY)((DWORD)msg->next_hbody + 1);
+    body = new_body_entry(mime_body, msg->next_index++, parent);
 
     if(IMimeBody_IsContentType(mime_body, "multipart", NULL) == S_OK)
     {
@@ -1812,7 +1811,7 @@ static HRESULT find_body(struct list *list, HBODY hbody, body_t **body)
 
     LIST_FOR_EACH_ENTRY(cur, list, body_t, entry)
     {
-        if(cur->hbody == hbody)
+        if(cur->index == HandleToUlong(hbody))
         {
             *body = cur;
             return S_OK;
@@ -1948,7 +1947,7 @@ static HRESULT WINAPI MimeMessage_GetBody(
 
     hr = get_body(This, location, hPivot, &body);
 
-    if(hr == S_OK) *phBody = body->hbody;
+    if(hr == S_OK) *phBody = UlongToHandle(body->index);
 
     return hr;
 }
@@ -2003,38 +2002,35 @@ static HRESULT WINAPI MimeMessage_CountBodies(
     return S_OK;
 }
 
-static HRESULT find_next(IMimeMessage *msg, LPFINDBODY find_body, HBODY *out)
+static HRESULT find_next(IMimeMessage *msg, body_t *body, LPFINDBODY find, HBODY *out)
 {
-    HRESULT hr;
-    IMimeBody *mime_body;
+    MimeMessage *This = (MimeMessage *)msg;
+    struct list *ptr;
     HBODY next;
 
-    if(find_body->dwReserved == 0)
-        find_body->dwReserved = (DWORD)HBODY_ROOT;
-    else
+    for (;;)
     {
-        hr = IMimeMessage_GetBody(msg, IBL_FIRST, (HBODY)find_body->dwReserved, &next);
-        if(hr == S_OK)
-            find_body->dwReserved = (DWORD)next;
+        if (!body) ptr = list_head( &This->body_tree );
         else
         {
-            hr = IMimeMessage_GetBody(msg, IBL_NEXT, (HBODY)find_body->dwReserved, &next);
-            if(hr == S_OK)
-                find_body->dwReserved = (DWORD)next;
-            else
-                return MIME_E_NOT_FOUND;
+            ptr = list_head( &body->children );
+            while (!ptr)
+            {
+                if (!body->parent) return MIME_E_NOT_FOUND;
+                if (!(ptr = list_next( &body->parent->children, &body->entry ))) body = body->parent;
+            }
         }
-    }
 
-    hr = IMimeMessage_BindToObject(msg, (HBODY)find_body->dwReserved, &IID_IMimeBody, (void**)&mime_body);
-    if(IMimeBody_IsContentType(mime_body, find_body->pszPriType, find_body->pszSubType) == S_OK)
-    {
-        IMimeBody_Release(mime_body);
-        *out = (HBODY)find_body->dwReserved;
-        return S_OK;
+        body = LIST_ENTRY( ptr, body_t, entry );
+        next = UlongToHandle( body->index );
+        find->dwReserved = body->index;
+        if (IMimeBody_IsContentType(body->mime_body, find->pszPriType, find->pszSubType) == S_OK)
+        {
+            *out = next;
+            return S_OK;
+        }
     }
-    IMimeBody_Release(mime_body);
-    return find_next(msg, find_body, out);
+    return MIME_E_NOT_FOUND;
 }
 
 static HRESULT WINAPI MimeMessage_FindFirst(
@@ -2045,7 +2041,7 @@ static HRESULT WINAPI MimeMessage_FindFirst(
     TRACE("(%p)->(%p, %p)\n", iface, pFindBody, phBody);
 
     pFindBody->dwReserved = 0;
-    return find_next(iface, pFindBody, phBody);
+    return find_next( iface, NULL, pFindBody, phBody );
 }
 
 static HRESULT WINAPI MimeMessage_FindNext(
@@ -2053,9 +2049,15 @@ static HRESULT WINAPI MimeMessage_FindNext(
     LPFINDBODY pFindBody,
     LPHBODY phBody)
 {
+    MimeMessage *This = (MimeMessage *)iface;
+    body_t *body;
+    HRESULT hr;
+
     TRACE("(%p)->(%p, %p)\n", iface, pFindBody, phBody);
 
-    return find_next(iface, pFindBody, phBody);
+    hr = find_body( &This->body_tree, UlongToHandle( pFindBody->dwReserved ), &body );
+    if (hr != S_OK) return MIME_E_NOT_FOUND;
+    return find_next( iface, body, pFindBody, phBody );
 }
 
 static HRESULT WINAPI MimeMessage_ResolveURL(
@@ -2562,7 +2564,7 @@ HRESULT MimeMessage_create(IUnknown *outer, void **obj)
     This->refs = 1;
     This->stream = NULL;
     list_init(&This->body_tree);
-    This->next_hbody = (HBODY)1;
+    This->next_index = 1;
 
     *obj = &This->lpVtbl;
     return S_OK;
index 8ceb252..f1f148b 100644 (file)
@@ -61,7 +61,6 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
 
 HRESULT WINAPI DllCanUnloadNow(void)
 {
-    FIXME("\n");
     return S_FALSE;
 }
 
index 0068827..c1c8e60 100644 (file)
@@ -324,6 +324,7 @@ HRESULT regexp_match_next(script_ctx_t*,DispatchEx*,DWORD,const WCHAR*,DWORD,con
         DWORD*,DWORD*,match_result_t*);
 HRESULT regexp_match(script_ctx_t*,DispatchEx*,const WCHAR*,DWORD,BOOL,match_result_t**,DWORD*);
 HRESULT parse_regexp_flags(const WCHAR*,DWORD,DWORD*);
+HRESULT regexp_string_match(script_ctx_t*,DispatchEx*,BSTR,VARIANT*,jsexcept_t*);
 
 static inline VARIANT *get_arg(DISPPARAMS *dp, DWORD i)
 {
index 0457545..7861d22 100644 (file)
@@ -2384,7 +2384,7 @@ SimpleMatch(REGlobalData *gData, REMatchState *x, REOp op,
     RECharSet *charSet;
 
     const char *opname = reop_names[op];
-    TRACE("\n%06d: %*s%s\n", pc - gData->regexp->program,
+    TRACE("\n%06d: %*s%s\n", (int)(pc - gData->regexp->program),
           (int)gData->stateStackTop * 2, "", opname);
 
     switch (op) {
@@ -2623,7 +2623,7 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
 
     for (;;) {
         const char *opname = reop_names[op];
-        TRACE("\n%06d: %*s%s\n", pc - gData->regexp->program,
+        TRACE("\n%06d: %*s%s\n", (int)(pc - gData->regexp->program),
               (int)gData->stateStackTop * 2, "", opname);
 
         if (REOP_IS_SIMPLE(op)) {
@@ -3637,25 +3637,25 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, VARIANT *arg, jsexce
         hres = to_string(ctx, arg, ei, &string);
         if(FAILED(hres))
             return hres;
+        length = SysStringLen(string);
     }else {
-        string = SysAllocStringLen(NULL, 0);
-        if(!string)
-            return E_OUTOFMEMORY;
+        string = NULL;
+        length = 0;
     }
 
-    if(regexp->last_index < 0) {
-        SysFreeString(string);
-        set_last_index(regexp, 0);
-        *ret = VARIANT_FALSE;
-        if(input) {
-            *input = NULL;
+    if(regexp->jsregexp->flags & JSREG_GLOB) {
+        if(regexp->last_index < 0) {
+            SysFreeString(string);
+            set_last_index(regexp, 0);
+            *ret = VARIANT_FALSE;
+            if(input) {
+                *input = NULL;
+            }
+            return S_OK;
         }
-        return S_OK;
-    }
 
-    length = SysStringLen(string);
-    if(regexp->jsregexp->flags & JSREG_GLOB)
         last_index = regexp->last_index;
+    }
 
     cp = string + last_index;
     hres = regexp_match_next(ctx, &regexp->dispex, REM_RESET_INDEX, string, length, &cp, parens,
@@ -3878,6 +3878,87 @@ HRESULT create_regexp_var(script_ctx_t *ctx, VARIANT *src_arg, VARIANT *flags_ar
     return create_regexp(ctx, src, -1, flags, ret);
 }
 
+HRESULT regexp_string_match(script_ctx_t *ctx, DispatchEx *re, BSTR str,
+        VARIANT *retv, jsexcept_t *ei)
+{
+    RegExpInstance *regexp = (RegExpInstance*)re;
+    match_result_t *match_result;
+    DWORD match_cnt, i, length;
+    DispatchEx *array;
+    VARIANT var;
+    HRESULT hres;
+
+    length = SysStringLen(str);
+
+    if(!(regexp->jsregexp->flags & JSREG_GLOB)) {
+        match_result_t match, *parens = NULL;
+        DWORD parens_cnt, parens_size = 0;
+        const WCHAR *cp = str;
+
+        hres = regexp_match_next(ctx, &regexp->dispex, 0, str, length, &cp, &parens, &parens_size, &parens_cnt, &match);
+        if(FAILED(hres))
+            return hres;
+
+        if(retv) {
+            if(hres == S_OK) {
+                IDispatch *ret;
+
+                hres = create_match_array(ctx, str, &match, parens, parens_cnt, ei, &ret);
+                if(SUCCEEDED(hres)) {
+                    V_VT(retv) = VT_DISPATCH;
+                    V_DISPATCH(retv) = ret;
+                }
+            }else {
+                V_VT(retv) = VT_NULL;
+            }
+        }
+
+        heap_free(parens);
+        return S_OK;
+    }
+
+    hres = regexp_match(ctx, &regexp->dispex, str, length, FALSE, &match_result, &match_cnt);
+    if(FAILED(hres))
+        return hres;
+
+    if(!match_cnt) {
+        TRACE("no match\n");
+
+        if(retv)
+            V_VT(retv) = VT_NULL;
+        return S_OK;
+    }
+
+    hres = create_array(ctx, match_cnt, &array);
+    if(FAILED(hres))
+        return hres;
+
+    V_VT(&var) = VT_BSTR;
+
+    for(i=0; i < match_cnt; i++) {
+        V_BSTR(&var) = SysAllocStringLen(match_result[i].str, match_result[i].len);
+        if(!V_BSTR(&var)) {
+            hres = E_OUTOFMEMORY;
+            break;
+        }
+
+        hres = jsdisp_propput_idx(array, i, &var, ei, NULL/*FIXME*/);
+        SysFreeString(V_BSTR(&var));
+        if(FAILED(hres))
+            break;
+    }
+
+    heap_free(match_result);
+
+    if(SUCCEEDED(hres) && retv) {
+        V_VT(retv) = VT_DISPATCH;
+        V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(array);
+    }else {
+        jsdisp_release(array);
+    }
+    return hres;
+}
+
 static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
index df43fee..510dcc2 100644 (file)
@@ -622,11 +622,9 @@ static HRESULT String_match(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
     const WCHAR *str;
-    match_result_t *match_result;
     DispatchEx *regexp;
-    DispatchEx *array;
-    VARIANT var, *arg_var;
-    DWORD length, match_cnt, i;
+    VARIANT *arg_var;
+    DWORD length;
     BSTR val_str = NULL;
     HRESULT hres = S_OK;
 
@@ -645,7 +643,7 @@ static HRESULT String_match(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP
     case VT_DISPATCH:
         regexp = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg_var));
         if(regexp) {
-            if(regexp->builtin_info->class == JSCLASS_REGEXP)
+            if(is_class(regexp, JSCLASS_REGEXP))
                 break;
             jsdisp_release(regexp);
         }
@@ -664,54 +662,17 @@ static HRESULT String_match(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP
     }
 
     hres = get_string_val(ctx, jsthis, ei, &str, &length, &val_str);
-    if(SUCCEEDED(hres))
-        hres = regexp_match(ctx, regexp, str, length, FALSE, &match_result, &match_cnt);
-    jsdisp_release(regexp);
-    if(FAILED(hres)) {
-        SysFreeString(val_str);
-        return hres;
-    }
-
-    if(!match_cnt) {
-        TRACE("no match\n");
-
-        if(retv)
-            V_VT(retv) = VT_NULL;
-
-        SysFreeString(val_str);
-        return S_OK;
-    }
-
-    hres = create_array(ctx, match_cnt, &array);
-    if(FAILED(hres)) {
-        SysFreeString(val_str);
-        return hres;
-    }
-
-    V_VT(&var) = VT_BSTR;
-
-    for(i=0; i < match_cnt; i++) {
-        V_BSTR(&var) = SysAllocStringLen(match_result[i].str, match_result[i].len);
-        if(!V_BSTR(&var)) {
+    if(SUCCEEDED(hres)) {
+        if(!val_str)
+            val_str = SysAllocStringLen(str, length);
+        if(val_str)
+            hres = regexp_string_match(ctx, regexp, val_str, retv, ei);
+        else
             hres = E_OUTOFMEMORY;
-            break;
-        }
-
-        hres = jsdisp_propput_idx(array, i, &var, ei, NULL/*FIXME*/);
-        SysFreeString(V_BSTR(&var));
-        if(FAILED(hres))
-            break;
     }
 
-    heap_free(match_result);
+    jsdisp_release(regexp);
     SysFreeString(val_str);
-
-    if(SUCCEEDED(hres) && retv) {
-        V_VT(retv) = VT_DISPATCH;
-        V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(array);
-    }else {
-        jsdisp_release(array);
-    }
     return hres;
 }
 
index 97c0447..848d4f8 100644 (file)
@@ -741,7 +741,7 @@ GetShortPathNameW (
     }
 
     /* check for drive letter */
-    if (longpath[1] == ':' )
+    if (longpath[0] != '/' && longpath[1] == ':' )
     {
         tmpshortpath[0] = longpath[0];
         tmpshortpath[1] = ':';
@@ -772,7 +772,7 @@ GetShortPathNameW (
         tmplen = p - (longpath + lp);
         lstrcpynW(tmpshortpath + sp, longpath + lp, tmplen + 1);
         /* Check, if the current element is a valid dos name */
-        if (tmplen <= 8+1+3+1)
+        if (tmplen <= 8+1+3)
         {
             BOOLEAN spaces;
             memcpy(ustr_buf, longpath + lp, tmplen * sizeof(WCHAR));
index b952a28..cba32d9 100644 (file)
 @ stdcall WaitNamedPipeW (wstr long)
 @ stdcall WideCharToMultiByte(long long wstr long ptr long ptr ptr)
 @ stdcall WinExec(str long)
-#ifdef _M_AMD64
 @ stdcall Wow64EnableWow64FsRedirection(long)
 @ stdcall Wow64DisableWow64FsRedirection(long)
 @ stdcall Wow64RevertWow64FsRedirection(long)
-#endif
 @ stdcall WriteConsoleA(long ptr long ptr ptr)
 @ stdcall WriteConsoleInputA(long ptr long ptr)
 @ stdcall WriteConsoleInputVDMA(long long long long)
index d22e9ba..c852f34 100644 (file)
@@ -885,9 +885,9 @@ NlsGetCacheUpdateCount(VOID)
     return 0;
 }
 
-BOOL
+BOOLEAN
 WINAPI
-Wow64EnableWow64FsRedirection (BOOL Wow64EnableWow64FsRedirection)
+Wow64EnableWow64FsRedirection (BOOLEAN Wow64EnableWow64FsRedirection)
 {
     STUB;
     return FALSE;
index b17e074..3224188 100644 (file)
@@ -1375,7 +1375,7 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo
     }
 
     /* Verified with the Adobe PS Driver, that w2k does not use di.Version */
-    RegSetValueExW(hdrv, versionW, 0, REG_DWORD, (LPBYTE) &env->driverversion,
+    RegSetValueExW(hdrv, versionW, 0, REG_DWORD, (const BYTE*) &env->driverversion,
                    sizeof(DWORD));
 
     RegSetValueExW(hdrv, driverW, 0, REG_SZ, (LPBYTE) di.pDriverPath,
@@ -1395,7 +1395,7 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo
         RegSetValueExW(hdrv, help_fileW, 0, REG_SZ, (LPBYTE) di.pHelpFile,
                        (lstrlenW(di.pHelpFile)+1)* sizeof(WCHAR));
     else
-        RegSetValueExW(hdrv, help_fileW, 0, REG_SZ, (LPBYTE)emptyW, sizeof(emptyW));
+        RegSetValueExW(hdrv, help_fileW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW));
     apd_copyfile(di.pHelpFile, &apd);
 
 
@@ -1404,7 +1404,7 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo
         RegSetValueExW(hdrv, dependent_filesW, 0, REG_MULTI_SZ, (LPBYTE) di.pDependentFiles,
                        multi_sz_lenW(di.pDependentFiles));
     else
-        RegSetValueExW(hdrv, dependent_filesW, 0, REG_MULTI_SZ, (LPBYTE)emptyW, sizeof(emptyW));
+        RegSetValueExW(hdrv, dependent_filesW, 0, REG_MULTI_SZ, (const BYTE*)emptyW, sizeof(emptyW));
     while ((ptr != NULL) && (ptr[0])) {
         if (apd_copyfile(ptr, &apd)) {
             ptr += lstrlenW(ptr) + 1;
@@ -1420,20 +1420,20 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo
         RegSetValueExW(hdrv, monitorW, 0, REG_SZ, (LPBYTE) di.pMonitorName,
                        (lstrlenW(di.pMonitorName)+1)* sizeof(WCHAR));
     else
-        RegSetValueExW(hdrv, monitorW, 0, REG_SZ, (LPBYTE)emptyW, sizeof(emptyW));
+        RegSetValueExW(hdrv, monitorW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW));
 
     if (di.pDefaultDataType)
         RegSetValueExW(hdrv, datatypeW, 0, REG_SZ, (LPBYTE) di.pDefaultDataType,
                        (lstrlenW(di.pDefaultDataType)+1)* sizeof(WCHAR));
     else
-        RegSetValueExW(hdrv, datatypeW, 0, REG_SZ, (LPBYTE)emptyW, sizeof(emptyW));
+        RegSetValueExW(hdrv, datatypeW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW));
 
     /* settings for level 4 */
     if (di.pszzPreviousNames)
         RegSetValueExW(hdrv, previous_namesW, 0, REG_MULTI_SZ, (LPBYTE) di.pszzPreviousNames,
                        multi_sz_lenW(di.pszzPreviousNames));
     else
-        RegSetValueExW(hdrv, previous_namesW, 0, REG_MULTI_SZ, (LPBYTE)emptyW, sizeof(emptyW));
+        RegSetValueExW(hdrv, previous_namesW, 0, REG_MULTI_SZ, (const BYTE*)emptyW, sizeof(emptyW));
 
     if (level > 5) TRACE("level %u for Driver %s is incomplete\n", level, debugstr_w(di.pName));
 
index 9b7c8e1..1d5bdc0 100644 (file)
@@ -36,7 +36,7 @@ LpkDllInitialize (
         case DLL_PROCESS_ATTACH:
             DisableThreadLibraryCalls(hDll);
             /* Tell usp10 it is activated usp10 */
-            LpkPresent();
+            //LpkPresent();
             break;
 
         default:
index d77525c..1c15dc5 100644 (file)
@@ -89,6 +89,7 @@ static        DWORD   MCIAVI_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
     wma->hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
     wma->wDevID = modp->wDeviceID;
     wma->wCommandTable = mciLoadCommandResource(MCIAVI_hInstance, mciAviWStr, 0);
+    wma->dwStatus = MCI_MODE_NOT_READY;
     modp->wCustomCommandTable = wma->wCommandTable;
     modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO;
     mciSetDriverData(wma->wDevID, (DWORD_PTR)wma);
@@ -301,11 +302,11 @@ DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
     wma = MCIAVI_mciGetOpenDev(wDevID);
     if (wma == NULL)   return MCIERR_INVALID_DEVICE_ID;
 
+    MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
     EnterCriticalSection(&wma->cs);
 
     if (wma->nUseCount == 1) {
-       if (wma->dwStatus != MCI_MODE_STOP)
-           dwRet = MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
        MCIAVI_CleanUp(wma);
 
        if ((dwFlags & MCI_NOTIFY) && lpParms) {
@@ -836,14 +837,14 @@ static    DWORD   MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_P
 {
     WINE_MCIAVI *wma;
 
-    FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms);
-
     if (lpParms == NULL)       return MCIERR_NULL_PARAMETER_BLOCK;
 
+    FIXME("(%04x, %08x, %p) Item %04x: stub\n", wDevID, dwFlags, lpParms, dwFlags & MCI_DGV_SETAUDIO_ITEM ? lpParms->dwItem : 0);
+
     wma = MCIAVI_mciGetOpenDev(wDevID);
     if (wma == NULL)           return MCIERR_INVALID_DEVICE_ID;
 
-    return MCIERR_UNSUPPORTED_FUNCTION; /* like w2k */
+    return 0;
 }
 
 /******************************************************************************
@@ -870,14 +871,14 @@ static    DWORD   MCIAVI_mciSetVideo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETVIDEO_P
 {
     WINE_MCIAVI *wma;
 
-    FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms);
-
     if (lpParms == NULL)       return MCIERR_NULL_PARAMETER_BLOCK;
 
+    FIXME("(%04x, %08x, %p) Item %04x: stub\n", wDevID, dwFlags, lpParms, dwFlags & MCI_DGV_SETVIDEO_ITEM ? lpParms->dwItem : 0);
+
     wma = MCIAVI_mciGetOpenDev(wDevID);
     if (wma == NULL)           return MCIERR_INVALID_DEVICE_ID;
 
-    return MCIERR_UNSUPPORTED_FUNCTION; /* like w2k */
+    return 0;
 }
 
 /******************************************************************************
index cf9132c..6ea996a 100644 (file)
@@ -420,7 +420,8 @@ static DWORD MCICDA_Open(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpOpenPar
     if (dwFlags & MCI_OPEN_ELEMENT) {
         if (dwFlags & MCI_OPEN_ELEMENT_ID) {
             WARN("MCI_OPEN_ELEMENT_ID %p! Abort\n", lpOpenParms->lpstrElementName);
-            return MCIERR_NO_ELEMENT_ALLOWED;
+            ret = MCIERR_NO_ELEMENT_ALLOWED;
+            goto the_error;
         }
         TRACE("MCI_OPEN_ELEMENT element name: %s\n", debugstr_w(lpOpenParms->lpstrElementName));
         if (!isalpha(lpOpenParms->lpstrElementName[0]) || lpOpenParms->lpstrElementName[1] != ':' ||
@@ -483,6 +484,8 @@ static DWORD MCICDA_Close(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParm
 
     if (wmcda == NULL)         return MCIERR_INVALID_DEVICE_ID;
 
+    MCICDA_Stop(wDevID, MCI_WAIT, NULL);
+
     if (--wmcda->nUseCount == 0) {
        CloseHandle(wmcda->handle);
     }
index b98e163..c826de1 100644 (file)
@@ -153,7 +153,8 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags,
 
     MCIQTZ_mciStop(wDevID, MCI_WAIT, NULL);
 
-    CoInitializeEx(NULL, COINIT_MULTITHREADED);
+    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
+    wma->uninit = SUCCEEDED(hr);
 
     hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, (LPVOID*)&wma->pgraph);
     if (FAILED(hr)) {
@@ -197,7 +198,8 @@ err:
         IMediaControl_Release(wma->pmctrl);
     wma->pmctrl = NULL;
 
-    CoUninitialize();
+    if (wma->uninit)
+        CoUninitialize();
 
     return MCIERR_INTERNAL;
 }
@@ -220,7 +222,8 @@ static DWORD MCIQTZ_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpP
     if (wma->opened) {
         IGraphBuilder_Release(wma->pgraph);
         IMediaControl_Release(wma->pmctrl);
-        CoUninitialize();
+        if (wma->uninit)
+            CoUninitialize();
         wma->opened = FALSE;
     }
 
index dcfcad0..caf80de 100644 (file)
@@ -28,6 +28,7 @@
 typedef struct {
     MCIDEVICEID    wDevID;
     BOOL           opened;
+    BOOL           uninit;
     IGraphBuilder* pgraph;
     IMediaControl* pmctrl;
     BOOL           started;
index 301428d..87753c3 100644 (file)
@@ -62,6 +62,7 @@ typedef struct tagWINE_MCIMIDI {
     UINT               wDevID;                 /* the MCI one */
     HMIDI              hMidi;
     int                        nUseCount;              /* Incremented for each shared open          */
+    WORD               wPort;                  /* the WINMM device unit */
     WORD               wNotifyDeviceID;        /* MCI device ID with a pending notification */
     HANDLE             hCallback;              /* Callback handle for pending notification  */
     HMMIO              hFile;                  /* mmio file handle open as Element          */
@@ -726,6 +727,7 @@ static DWORD MIDI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpParms)
 
     wmm->hFile = 0;
     wmm->hMidi = 0;
+    wmm->wPort = MIDI_MAPPER;
     wmm->lpstrElementName = NULL;
     dwDeviceID = lpParms->wDeviceID;
 
@@ -962,8 +964,8 @@ static DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
        MIDI_mciReadNextEvent(wmm, mmt); /* FIXME == 0 */
     }
 
-    dwRet = midiOutOpen((LPHMIDIOUT)&wmm->hMidi, MIDIMAPPER, 0L, 0L, CALLBACK_NULL);
-    /* dwRet = midiInOpen(&wmm->hMidi, MIDIMAPPER, 0L, 0L, CALLBACK_NULL);*/
+    dwRet = midiOutOpen((LPHMIDIOUT)&wmm->hMidi, wmm->wPort, 0L, 0L, CALLBACK_NULL);
+    /* dwRet = midiInOpen(&wmm->hMidi, wmm->wPort, 0L, 0L, CALLBACK_NULL);*/
     if (dwRet != MMSYSERR_NOERROR) {
        return dwRet;
     }
@@ -1290,7 +1292,7 @@ static DWORD MIDI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa
 /**************************************************************************
  *                             MIDI_mciSet                     [internal]
  */
-static DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
+static DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SEQ_SET_PARMS lpParms)
 {
     WINE_MCIMIDI*      wmm = MIDI_mciGetOpenDev(wDevID);
 
@@ -1359,8 +1361,15 @@ static DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
        TRACE("MCI_SEQ_SET_SLAVE !\n");
     if (dwFlags & MCI_SEQ_SET_OFFSET)
        TRACE("MCI_SEQ_SET_OFFSET !\n");
-    if (dwFlags & MCI_SEQ_SET_PORT)
-       TRACE("MCI_SEQ_SET_PORT !\n");
+    if (dwFlags & MCI_SEQ_SET_PORT) {
+       TRACE("MCI_SEQ_SET_PORT = %d\n", lpParms->dwPort);
+       if ((UINT16)lpParms->dwPort != (UINT16)MIDI_MAPPER &&
+           (UINT16)lpParms->dwPort >= midiOutGetNumDevs())
+           /* FIXME: input/output port distinction? */
+           return MCIERR_SEQ_PORT_NONEXISTENT;
+       /* FIXME: Native manages to swap the device while playing! */
+       wmm->wPort = lpParms->dwPort;
+    }
     if (dwFlags & MCI_SEQ_SET_TEMPO)
        TRACE("MCI_SEQ_SET_TEMPO !\n");
     return 0;
@@ -1459,8 +1468,13 @@ static DWORD MIDI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpPar
            lpParms->dwReturn = 0;
            break;
        case MCI_SEQ_STATUS_PORT:
-           TRACE("MCI_SEQ_STATUS_PORT (%u)!\n", wmm->wDevID);
-           lpParms->dwReturn = MIDI_MAPPER;
+           if (wmm->wPort != (UINT16)MIDI_MAPPER)
+               lpParms->dwReturn = wmm->wPort;
+           else {
+               lpParms->dwReturn = MAKEMCIRESOURCE(MIDI_MAPPER, MCI_SEQ_MAPPER_S);
+               ret = MCI_RESOURCE_RETURNED;
+           }
+           TRACE("MCI_SEQ_STATUS_PORT (%u) => %d\n", wmm->wDevID, wmm->wPort);
            break;
        case MCI_SEQ_STATUS_TEMPO:
            TRACE("MCI_SEQ_STATUS_TEMPO !\n");
@@ -1664,7 +1678,7 @@ LRESULT CALLBACK MCIMIDI_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
     case MCI_PLAY:             return MIDI_mciPlay      (dwDevID, dwParam1, (LPMCI_PLAY_PARMS)      dwParam2);
     case MCI_RECORD:           return MIDI_mciRecord    (dwDevID, dwParam1, (LPMCI_RECORD_PARMS)    dwParam2);
     case MCI_STOP:             return MIDI_mciStop      (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)   dwParam2);
-    case MCI_SET:              return MIDI_mciSet       (dwDevID, dwParam1, (LPMCI_SET_PARMS)       dwParam2);
+    case MCI_SET:              return MIDI_mciSet       (dwDevID, dwParam1, (LPMCI_SEQ_SET_PARMS)       dwParam2);
     case MCI_PAUSE:            return MIDI_mciPause     (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)   dwParam2);
     case MCI_RESUME:           return MIDI_mciResume    (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)   dwParam2);
     case MCI_STATUS:           return MIDI_mciStatus    (dwDevID, dwParam1, (LPMCI_STATUS_PARMS)    dwParam2);
index 24e75ee..87dc260 100644 (file)
@@ -47,6 +47,8 @@ typedef struct {
     WAVEFORMATEX               wfxRef;
     LPWAVEFORMATEX             lpWaveFormat;   /* Points to wfxRef until set by OPEN or RECORD */
     BOOL                       fInput;         /* FALSE = Output, TRUE = Input */
+    WORD                       wInput;         /* wave input device */
+    WORD                       wOutput;        /* wave output device */
     volatile WORD              dwStatus;       /* one from MCI_MODE_xxxx */
     DWORD                      dwMciTimeFormat;/* One of the supported MCI_FORMAT_xxxx */
     DWORD                      dwPosition;     /* position in bytes in chunk */
@@ -529,6 +531,7 @@ static LRESULT WAVE_mciOpen(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_P
 
     wmw->nUseCount++;
 
+    wmw->wInput = wmw->wOutput = WAVE_MAPPER;
     wmw->fInput = FALSE;
     wmw->hWave = 0;
     wmw->dwStatus = MCI_MODE_NOT_READY;
@@ -831,8 +834,7 @@ static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt,
      */
     mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */
 
-    /* FIXME: how to choose between several output channels ? here mapper is forced */
-    dwRet = waveOutOpen((HWAVEOUT *)&wmw->hWave, WAVE_MAPPER, wmw->lpWaveFormat,
+    dwRet = waveOutOpen((HWAVEOUT *)&wmw->hWave, wmw->wOutput, wmw->lpWaveFormat,
                        (DWORD_PTR)WAVE_mciPlayCallback, (DWORD_PTR)wmw, CALLBACK_FUNCTION);
 
     if (dwRet != 0) {
@@ -1064,11 +1066,7 @@ static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt
      */
     mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */
 
-    /* By default the device will be opened for output, the MCI_CUE function is there to
-     * change from output to input and back
-     */
-    /* FIXME: how to choose between several output channels ? here mapper is forced */
-    dwRet = waveInOpen((HWAVEIN*)&wmw->hWave, WAVE_MAPPER, wmw->lpWaveFormat,
+    dwRet = waveInOpen((HWAVEIN*)&wmw->hWave, wmw->wInput, wmw->lpWaveFormat,
                        (DWORD_PTR)WAVE_mciRecordCallback, (DWORD_PTR)wmw, CALLBACK_FUNCTION);
 
     if (dwRet != MMSYSERR_NOERROR) {
@@ -1279,7 +1277,7 @@ static DWORD WAVE_mciSeek(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lp
 /**************************************************************************
  *                             WAVE_mciSet                     [internal]
  */
-static DWORD WAVE_mciSet(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
+static DWORD WAVE_mciSet(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_SET_PARMS lpParms)
 {
     WINE_MCIWAVE*      wmw = WAVE_mciGetOpenDev(wDevID);
 
@@ -1337,44 +1335,64 @@ static DWORD WAVE_mciSet(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpPa
         default:                        WARN("Unknown audio channel %u\n", lpParms->dwAudio); break;
         }
     }
-    if (dwFlags & MCI_WAVE_INPUT)
-       TRACE("MCI_WAVE_INPUT !\n");
-    if (dwFlags & MCI_WAVE_OUTPUT)
-       TRACE("MCI_WAVE_OUTPUT !\n");
-    if (dwFlags & MCI_WAVE_SET_ANYINPUT)
-       TRACE("MCI_WAVE_SET_ANYINPUT !\n");
-    if (dwFlags & MCI_WAVE_SET_ANYOUTPUT)
-       TRACE("MCI_WAVE_SET_ANYOUTPUT !\n");
+    if (dwFlags & MCI_WAVE_INPUT) {
+       TRACE("MCI_WAVE_INPUT = %d\n", lpParms->wInput);
+       if (lpParms->wInput >= waveInGetNumDevs())
+           return MCIERR_OUTOFRANGE;
+       if (wmw->wInput != (WORD)lpParms->wInput)
+           WAVE_mciStop(wDevID, MCI_WAIT, NULL);
+       wmw->wInput = lpParms->wInput;
+    }
+    if (dwFlags & MCI_WAVE_OUTPUT) {
+       TRACE("MCI_WAVE_OUTPUT = %d\n", lpParms->wOutput);
+       if (lpParms->wOutput >= waveOutGetNumDevs())
+           return MCIERR_OUTOFRANGE;
+       if (wmw->wOutput != (WORD)lpParms->wOutput)
+           WAVE_mciStop(wDevID, MCI_WAIT, NULL);
+       wmw->wOutput = lpParms->wOutput;
+    }
+    if (dwFlags & MCI_WAVE_SET_ANYINPUT) {
+       TRACE("MCI_WAVE_SET_ANYINPUT\n");
+       if (wmw->wInput != (WORD)lpParms->wInput)
+           WAVE_mciStop(wDevID, MCI_WAIT, NULL);
+       wmw->wInput = WAVE_MAPPER;
+    }
+    if (dwFlags & MCI_WAVE_SET_ANYOUTPUT) {
+       TRACE("MCI_WAVE_SET_ANYOUTPUT\n");
+       if (wmw->wOutput != (WORD)lpParms->wOutput)
+           WAVE_mciStop(wDevID, MCI_WAIT, NULL);
+       wmw->wOutput = WAVE_MAPPER;
+    }
     /* Set wave format parameters is refused after Open or Record.*/
     if (dwFlags & MCI_WAVE_SET_FORMATTAG) {
-       TRACE("MCI_WAVE_SET_FORMATTAG = %d\n", ((LPMCI_WAVE_SET_PARMS)lpParms)->wFormatTag);
+       TRACE("MCI_WAVE_SET_FORMATTAG = %d\n", lpParms->wFormatTag);
        if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
-       if (((LPMCI_WAVE_SET_PARMS)lpParms)->wFormatTag != WAVE_FORMAT_PCM)
+       if (lpParms->wFormatTag != WAVE_FORMAT_PCM)
            return MCIERR_OUTOFRANGE;
     }
     if (dwFlags & MCI_WAVE_SET_AVGBYTESPERSEC) {
        if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
-       wmw->wfxRef.nAvgBytesPerSec = ((LPMCI_WAVE_SET_PARMS)lpParms)->nAvgBytesPerSec;
+       wmw->wfxRef.nAvgBytesPerSec = lpParms->nAvgBytesPerSec;
        TRACE("MCI_WAVE_SET_AVGBYTESPERSEC = %d\n", wmw->wfxRef.nAvgBytesPerSec);
     }
     if (dwFlags & MCI_WAVE_SET_BITSPERSAMPLE) {
        if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
-       wmw->wfxRef.wBitsPerSample = ((LPMCI_WAVE_SET_PARMS)lpParms)->wBitsPerSample;
+       wmw->wfxRef.wBitsPerSample = lpParms->wBitsPerSample;
        TRACE("MCI_WAVE_SET_BITSPERSAMPLE = %d\n", wmw->wfxRef.wBitsPerSample);
     }
     if (dwFlags & MCI_WAVE_SET_BLOCKALIGN) {
        if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
-       wmw->wfxRef.nBlockAlign = ((LPMCI_WAVE_SET_PARMS)lpParms)->nBlockAlign;
+       wmw->wfxRef.nBlockAlign = lpParms->nBlockAlign;
        TRACE("MCI_WAVE_SET_BLOCKALIGN = %d\n", wmw->wfxRef.nBlockAlign);
     }
     if (dwFlags & MCI_WAVE_SET_CHANNELS) {
        if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
-       wmw->wfxRef.nChannels = ((LPMCI_WAVE_SET_PARMS)lpParms)->nChannels;
+       wmw->wfxRef.nChannels = lpParms->nChannels;
        TRACE("MCI_WAVE_SET_CHANNELS = %d\n", wmw->wfxRef.nChannels);
     }
     if (dwFlags & MCI_WAVE_SET_SAMPLESPERSEC) {
        if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
-       wmw->wfxRef.nSamplesPerSec = ((LPMCI_WAVE_SET_PARMS)lpParms)->nSamplesPerSec;
+       wmw->wfxRef.nSamplesPerSec = lpParms->nSamplesPerSec;
        TRACE("MCI_WAVE_SET_SAMPLESPERSEC = %d\n", wmw->wfxRef.nSamplesPerSec);
     }
     if (dwFlags & MCI_NOTIFY)
@@ -1500,24 +1518,34 @@ static DWORD WAVE_mciStatus(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_STATUS_PARM
            ret = MCI_RESOURCE_RETURNED;
            break;
        case MCI_WAVE_INPUT:
-           TRACE("MCI_WAVE_INPUT !\n");
-           lpParms->dwReturn = 0;
-           ret = MCIERR_WAVE_INPUTUNSPECIFIED;
+           if (wmw->wInput != (WORD)WAVE_MAPPER)
+               lpParms->dwReturn = wmw->wInput;
+           else {
+               lpParms->dwReturn = MAKEMCIRESOURCE(WAVE_MAPPER, WAVE_MAPPER_S);
+               ret = MCI_RESOURCE_RETURNED;
+           }
+           TRACE("MCI_WAVE_INPUT => %d\n", (signed)wmw->wInput);
            break;
        case MCI_WAVE_OUTPUT:
-           TRACE("MCI_WAVE_OUTPUT !\n");
-           {
-               UINT    id;
-               if (waveOutGetID(wmw->hWave, &id) == MMSYSERR_NOERROR) {
-                   lpParms->dwReturn = id;
-               } else {
-                   lpParms->dwReturn = 0;
-                   ret = MCIERR_WAVE_OUTPUTUNSPECIFIED;
-               }
+           if (wmw->wOutput != (WORD)WAVE_MAPPER)
+               lpParms->dwReturn = wmw->wOutput;
+           else {
+               lpParms->dwReturn = MAKEMCIRESOURCE(WAVE_MAPPER, WAVE_MAPPER_S);
+               ret = MCI_RESOURCE_RETURNED;
            }
+           TRACE("MCI_WAVE_OUTPUT => %d\n", (signed)wmw->wOutput);
            break;
        /* It is always ok to query wave format parameters,
         * except on auto-open yield MCIERR_UNSUPPORTED_FUNCTION. */
+       case MCI_WAVE_STATUS_FORMATTAG:
+           if (wmw->lpWaveFormat->wFormatTag != WAVE_FORMAT_PCM)
+               lpParms->dwReturn = wmw->lpWaveFormat->wFormatTag;
+           else {
+               lpParms->dwReturn = MAKEMCIRESOURCE(WAVE_FORMAT_PCM, WAVE_FORMAT_PCM_S);
+               ret = MCI_RESOURCE_RETURNED;
+           }
+           TRACE("MCI_WAVE_FORMATTAG => %lu\n", lpParms->dwReturn);
+           break;
        case MCI_WAVE_STATUS_AVGBYTESPERSEC:
            lpParms->dwReturn = wmw->lpWaveFormat->nAvgBytesPerSec;
            TRACE("MCI_WAVE_STATUS_AVGBYTESPERSEC => %lu\n", lpParms->dwReturn);
@@ -1534,10 +1562,6 @@ static DWORD WAVE_mciStatus(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_STATUS_PARM
            lpParms->dwReturn = wmw->lpWaveFormat->nChannels;
            TRACE("MCI_WAVE_STATUS_CHANNELS => %lu\n", lpParms->dwReturn);
            break;
-       case MCI_WAVE_STATUS_FORMATTAG:
-           lpParms->dwReturn = wmw->lpWaveFormat->wFormatTag;
-           TRACE("MCI_WAVE_FORMATTAG => %lu\n", lpParms->dwReturn);
-           break;
        case MCI_WAVE_STATUS_SAMPLESPERSEC:
            lpParms->dwReturn = wmw->lpWaveFormat->nSamplesPerSec;
            TRACE("MCI_WAVE_STATUS_SAMPLESPERSEC => %lu\n", lpParms->dwReturn);
@@ -1705,7 +1729,7 @@ LRESULT CALLBACK MCIWAVE_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
     case MCI_PLAY:             return WAVE_mciPlay      (dwDevID, dwParam1, dwParam2, NULL);
     case MCI_RECORD:           return WAVE_mciRecord    (dwDevID, dwParam1, dwParam2, NULL);
     case MCI_STOP:             return WAVE_mciStop      (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);
-    case MCI_SET:              return WAVE_mciSet       (dwDevID, dwParam1, (LPMCI_SET_PARMS)         dwParam2);
+    case MCI_SET:              return WAVE_mciSet       (dwDevID, dwParam1, (LPMCI_WAVE_SET_PARMS)    dwParam2);
     case MCI_PAUSE:            return WAVE_mciPause     (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);
     case MCI_RESUME:           return WAVE_mciResume    (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);
     case MCI_STATUS:           return WAVE_mciStatus    (dwDevID, dwParam1, (LPMCI_STATUS_PARMS)      dwParam2);
index df9cb03..b6f802e 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
-<group>
+<group xmlns:xi="http://www.w3.org/2001/XInclude">
 <module name="msacm32" type="win32dll" baseaddress="${BASEADDRESS_MSACM32}" installbase="system32" installname="msacm32.dll" unicode="yes">
        <importlibrary definition="msacm32.spec" />
        <include base="msacm32">.</include>
index 2fa0743..a014334 100644 (file)
@@ -5,6 +5,7 @@
        <define name="__WINESRC__" />
        <library>wine</library>
        <library>advapi32</library>
+       <library>shell32</library>
        <library>uuid</library>
        <file>corruntimehost.c</file>
        <file>mscoree_main.c</file>
index 9365f18..8e25cec 100644 (file)
@@ -7,7 +7,7 @@
 
 @ stub CallFunctionShim
 @ stub CloseCtrs
-@ stub ClrCreateManagedInstance
+@ stdcall ClrCreateManagedInstance(wstr ptr ptr)
 @ stub CoEEShutDownCOM
 @ stdcall CoInitializeCor(long)
 @ stub CoInitializeEE
index dcdc91a..0e6f252 100644 (file)
 
 #include <stdarg.h>
 
+#include "wine/unicode.h"
 #include "windef.h"
 #include "winbase.h"
 #include "winuser.h"
+#include "winnls.h"
 #include "winreg.h"
 #include "ole2.h"
+#include "shellapi.h"
 
 #include "initguid.h"
 #include "cor.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
 
-static LPWSTR get_mono_exe(void)
+static BOOL get_mono_path(LPWSTR path)
 {
-    static const WCHAR mono_exe[] = {'b','i','n','\\','m','o','n','o','.','e','x','e',' ',0};
     static const WCHAR mono_key[] = {'S','o','f','t','w','a','r','e','\\','N','o','v','e','l','l','\\','M','o','n','o',0};
     static const WCHAR defaul_clr[] = {'D','e','f','a','u','l','t','C','L','R',0};
     static const WCHAR install_root[] = {'S','d','k','I','n','s','t','a','l','l','R','o','o','t',0};
     static const WCHAR slash[] = {'\\',0};
 
-    WCHAR version[64], version_key[MAX_PATH], root[MAX_PATH], *ret;
-    DWORD len, size;
+    WCHAR version[64], version_key[MAX_PATH];
+    DWORD len;
     HKEY key;
 
     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, mono_key, 0, KEY_READ, &key))
-        return NULL;
+        return FALSE;
 
     len = sizeof(version);
     if (RegQueryValueExW(key, defaul_clr, 0, NULL, (LPBYTE)version, &len))
     {
         RegCloseKey(key);
-        return NULL;
+        return FALSE;
     }
     RegCloseKey(key);
 
@@ -64,24 +66,129 @@ static LPWSTR get_mono_exe(void)
     lstrcatW(version_key, version);
 
     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, version_key, 0, KEY_READ, &key))
-        return NULL;
+        return FALSE;
 
-    len = sizeof(root);
-    if (RegQueryValueExW(key, install_root, 0, NULL, (LPBYTE)root, &len))
+    len = sizeof(WCHAR) * MAX_PATH;
+    if (RegQueryValueExW(key, install_root, 0, NULL, (LPBYTE)path, &len))
     {
         RegCloseKey(key);
-        return NULL;
+        return FALSE;
     }
     RegCloseKey(key);
 
-    size = len + sizeof(slash) + sizeof(mono_exe);
-    if (!(ret = HeapAlloc(GetProcessHeap(), 0, size))) return NULL;
+    return TRUE;
+}
+
+static CRITICAL_SECTION mono_lib_cs;
+static CRITICAL_SECTION_DEBUG mono_lib_cs_debug =
+{
+    0, 0, &mono_lib_cs,
+    { &mono_lib_cs_debug.ProcessLocksList,
+      &mono_lib_cs_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": mono_lib_cs") }
+};
+static CRITICAL_SECTION mono_lib_cs = { &mono_lib_cs_debug, -1, 0, 0, 0, 0 };
+
+HMODULE mono_handle;
+
+void (*mono_config_parse)(const char *filename);
+MonoAssembly* (*mono_domain_assembly_open) (MonoDomain *domain, const char *name);
+void (*mono_jit_cleanup)(MonoDomain *domain);
+int (*mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]);
+MonoDomain* (*mono_jit_init)(const char *file);
+int (*mono_jit_set_trace_options)(const char* options);
+void (*mono_set_dirs)(const char *assembly_dir, const char *config_dir);
+
+static void set_environment(LPCWSTR bin_path)
+{
+    WCHAR path_env[MAX_PATH];
+    int len;
+
+    static const WCHAR pathW[] = {'P','A','T','H',0};
+
+    /* We have to modify PATH as Mono loads other DLLs from this directory. */
+    GetEnvironmentVariableW(pathW, path_env, sizeof(path_env)/sizeof(WCHAR));
+    len = strlenW(path_env);
+    path_env[len++] = ';';
+    strcpyW(path_env+len, bin_path);
+    SetEnvironmentVariableW(pathW, path_env);
+}
 
-    lstrcpyW(ret, root);
-    lstrcatW(ret, slash);
-    lstrcatW(ret, mono_exe);
+static HMODULE load_mono(void)
+{
+    static const WCHAR mono_dll[] = {'\\','b','i','n','\\','m','o','n','o','.','d','l','l',0};
+    static const WCHAR libmono_dll[] = {'\\','b','i','n','\\','l','i','b','m','o','n','o','.','d','l','l',0};
+    static const WCHAR bin[] = {'\\','b','i','n',0};
+    static const WCHAR lib[] = {'\\','l','i','b',0};
+    static const WCHAR etc[] = {'\\','e','t','c',0};
+    HMODULE result;
+    WCHAR mono_path[MAX_PATH], mono_dll_path[MAX_PATH+16], mono_bin_path[MAX_PATH+4];
+    WCHAR mono_lib_path[MAX_PATH+4], mono_etc_path[MAX_PATH+4];
+    char mono_lib_path_a[MAX_PATH], mono_etc_path_a[MAX_PATH];
+
+    EnterCriticalSection(&mono_lib_cs);
+
+    if (!mono_handle)
+    {
+        if (!get_mono_path(mono_path)) goto end;
+
+        strcpyW(mono_bin_path, mono_path);
+        strcatW(mono_bin_path, bin);
+        set_environment(mono_bin_path);
+
+        strcpyW(mono_lib_path, mono_path);
+        strcatW(mono_lib_path, lib);
+        WideCharToMultiByte(CP_UTF8, 0, mono_lib_path, -1, mono_lib_path_a, MAX_PATH, NULL, NULL);
+
+        strcpyW(mono_etc_path, mono_path);
+        strcatW(mono_etc_path, etc);
+        WideCharToMultiByte(CP_UTF8, 0, mono_etc_path, -1, mono_etc_path_a, MAX_PATH, NULL, NULL);
+
+        strcpyW(mono_dll_path, mono_path);
+        strcatW(mono_dll_path, mono_dll);
+        mono_handle = LoadLibraryW(mono_dll_path);
+
+        if (!mono_handle)
+        {
+            strcpyW(mono_dll_path, mono_path);
+            strcatW(mono_dll_path, libmono_dll);
+            mono_handle = LoadLibraryW(mono_dll_path);
+        }
+
+        if (!mono_handle) goto end;
+
+#define LOAD_MONO_FUNCTION(x) do { \
+    x = (void*)GetProcAddress(mono_handle, #x); \
+    if (!x) { \
+        mono_handle = NULL; \
+        goto end; \
+    } \
+} while (0);
+
+        LOAD_MONO_FUNCTION(mono_config_parse);
+        LOAD_MONO_FUNCTION(mono_domain_assembly_open);
+        LOAD_MONO_FUNCTION(mono_jit_cleanup);
+        LOAD_MONO_FUNCTION(mono_jit_exec);
+        LOAD_MONO_FUNCTION(mono_jit_init);
+        LOAD_MONO_FUNCTION(mono_jit_set_trace_options);
+        LOAD_MONO_FUNCTION(mono_set_dirs);
+
+#undef LOAD_MONO_FUNCTION
+
+        mono_set_dirs(mono_lib_path_a, mono_etc_path_a);
+
+        mono_config_parse(NULL);
+    }
+
+end:
+    result = mono_handle;
 
-    return ret;
+    LeaveCriticalSection(&mono_lib_cs);
+
+    if (!result)
+        MESSAGE("wine: Install the Windows version of Mono to run .NET executables\n");
+
+    return result;
 }
 
 HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor,
@@ -89,20 +196,16 @@ HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor
                                     DWORD startupFlags, REFCLSID rclsid,
                                     REFIID riid, LPVOID *ppv)
 {
-    WCHAR *mono_exe;
-
-    FIXME("(%s, %s, %s, %p, %d, %p, %p, %p): semi-stub!\n", debugstr_w(pwszVersion),
+    FIXME("(%s, %s, %s, %p, %d, %s, %s, %p): semi-stub!\n", debugstr_w(pwszVersion),
           debugstr_w(pwszBuildFlavor), debugstr_w(pwszHostConfigFile), pReserved,
-          startupFlags, rclsid, riid, ppv);
+          startupFlags, debugstr_guid(rclsid), debugstr_guid(riid), ppv);
 
-    if (!(mono_exe = get_mono_exe()))
+    if (!get_mono_path(NULL))
     {
         MESSAGE("wine: Install the Windows version of Mono to run .NET executables\n");
         return E_FAIL;
     }
 
-    HeapFree(GetProcessHeap(), 0, mono_exe);
-
     return S_OK;
 }
 
@@ -138,49 +241,73 @@ BOOL WINAPI _CorDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
     return TRUE;
 }
 
-__int32 WINAPI _CorExeMain(void)
+static void get_utf8_args(int *argc, char ***argv)
 {
-    STARTUPINFOW si;
-    PROCESS_INFORMATION pi;
-    WCHAR *mono_exe, *cmd_line;
-    DWORD size, exit_code;
+    WCHAR **argvw;
+    int size=0, i;
+    char *current_arg;
+
+    argvw = CommandLineToArgvW(GetCommandLineW(), argc);
 
-    if (!(mono_exe = get_mono_exe()))
+    for (i=0; i<*argc; i++)
     {
-        MESSAGE("install the Windows version of Mono to run .NET executables\n");
-        return -1;
+        size += sizeof(char*);
+        size += WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL);
     }
+    size += sizeof(char*);
 
-    size = (lstrlenW(mono_exe) + lstrlenW(GetCommandLineW()) + 1) * sizeof(WCHAR);
-    if (!(cmd_line = HeapAlloc(GetProcessHeap(), 0, size)))
+    *argv = HeapAlloc(GetProcessHeap(), 0, size);
+    current_arg = (char*)(*argv + *argc + 1);
+
+    for (i=0; i<*argc; i++)
     {
-        HeapFree(GetProcessHeap(), 0, mono_exe);
-        return -1;
+        (*argv)[i] = current_arg;
+        current_arg += WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, current_arg, size, NULL, NULL);
     }
 
-    lstrcpyW(cmd_line, mono_exe);
-    HeapFree(GetProcessHeap(), 0, mono_exe);
-    lstrcatW(cmd_line, GetCommandLineW());
+    (*argv)[*argc] = NULL;
 
-    TRACE("new command line: %s\n", debugstr_w(cmd_line));
+    HeapFree(GetProcessHeap(), 0, argvw);
+}
 
-    memset(&si, 0, sizeof(si));
-    si.cb = sizeof(si);
-    if (!CreateProcessW(NULL, cmd_line, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
+__int32 WINAPI _CorExeMain(void)
+{
+    int exit_code;
+    int trace_size;
+    char trace_setting[256];
+    int argc;
+    char **argv;
+    MonoDomain *domain;
+    MonoAssembly *assembly;
+    char filename[MAX_PATH];
+
+    if (!load_mono())
     {
-        HeapFree(GetProcessHeap(), 0, cmd_line);
         return -1;
     }
-    HeapFree(GetProcessHeap(), 0, cmd_line);
 
-    /* wait for the process to exit */
-    WaitForSingleObject(pi.hProcess, INFINITE);
-    GetExitCodeProcess(pi.hProcess, &exit_code);
+    get_utf8_args(&argc, &argv);
+
+    trace_size = GetEnvironmentVariableA("WINE_MONO_TRACE", trace_setting, sizeof(trace_setting));
+
+    if (trace_size)
+    {
+        mono_jit_set_trace_options(trace_setting);
+    }
+
+    GetModuleFileNameA(NULL, filename, MAX_PATH);
+
+    domain = mono_jit_init(filename);
+
+    assembly = mono_domain_assembly_open(domain, filename);
+
+    exit_code = mono_jit_exec(domain, assembly, argc, argv);
 
-    CloseHandle(pi.hThread);
-    CloseHandle(pi.hProcess);
+    mono_jit_cleanup(domain);
 
-    return (int)exit_code;
+    HeapFree(GetProcessHeap(), 0, argv);
+
+    return exit_code;
 }
 
 __int32 WINAPI _CorExeMain2(PBYTE ptrMemory, DWORD cntMemory, LPWSTR imageName, LPWSTR loaderName, LPWSTR cmdLine)
@@ -271,7 +398,7 @@ HRESULT WINAPI CoInitializeCor(DWORD fFlags)
 
 HRESULT WINAPI GetAssemblyMDImport(LPCWSTR szFileName, REFIID riid, IUnknown **ppIUnk)
 {
-    FIXME("(%p %s, %p, %p): stub\n", szFileName, debugstr_w(szFileName), riid, *ppIUnk);
+    FIXME("(%p %s, %s, %p): stub\n", szFileName, debugstr_w(szFileName), debugstr_guid(riid), *ppIUnk);
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
@@ -324,6 +451,12 @@ HRESULT WINAPI CorBindToCurrentRuntime(LPCWSTR filename, REFCLSID rclsid, REFIID
     return E_NOTIMPL;
 }
 
+STDAPI ClrCreateManagedInstance(LPCWSTR pTypeName, REFIID riid, void **ppObject)
+{
+    FIXME("(%s,%s,%p)\n", debugstr_w(pTypeName), debugstr_guid(riid), ppObject);
+    return E_NOTIMPL;
+}
+
 BOOL WINAPI StrongNameSignatureVerification(LPCWSTR filename, DWORD inFlags, DWORD* pOutFlags)
 {
     FIXME("(%s, 0x%X, %p): stub\n", debugstr_w(filename), inFlags, pOutFlags);
@@ -338,7 +471,7 @@ BOOL WINAPI StrongNameSignatureVerificationEx(LPCWSTR filename, BOOL forceVerifi
 
 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
 {
-    FIXME("(%p, %p, %p): stub\n", rclsid, riid, ppv);
+    FIXME("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
     if(!ppv)
         return E_INVALIDARG;
 
index f329455..f14da1d 100644 (file)
 
 extern IUnknown* create_corruntimehost(void);
 
+/* Mono 2.6 embedding */
+typedef struct _MonoDomain MonoDomain;
+typedef struct _MonoAssembly MonoAssembly;
+
+extern HMODULE mono_handle;
+
+extern void (*mono_config_parse)(const char *filename);
+extern MonoAssembly* (*mono_domain_assembly_open) (MonoDomain *domain, const char *name);
+extern void (*mono_jit_cleanup)(MonoDomain *domain);
+extern int (*mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]);
+extern MonoDomain* (*mono_jit_init)(const char *file);
+extern int (*mono_jit_set_trace_options)(const char* options);
+extern void (*mono_set_dirs)(const char *assembly_dir, const char *config_dir);
 
 #endif   /* __MSCOREE_PRIVATE__ */
diff --git a/dll/win32/msctf/displayattributemgr.c b/dll/win32/msctf/displayattributemgr.c
new file mode 100644 (file)
index 0000000..75248cd
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ *  ITfDisplayAttributeMgr implementation
+ *
+ *  Copyright 2010 CodeWeavers, Aric Stewart
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+
+#include "wine/debug.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "shlwapi.h"
+
+#include "msctf.h"
+#include "msctf_internal.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msctf);
+
+typedef struct tagDisplayAttributeMgr {
+    const ITfDisplayAttributeMgrVtbl *DisplayAttributeMgrVtbl;
+
+    LONG refCount;
+
+} DisplayAttributeMgr;
+
+static void DisplayAttributeMgr_Destructor(DisplayAttributeMgr *This)
+{
+    TRACE("destroying %p\n", This);
+
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI DisplayAttributeMgr_QueryInterface(ITfDisplayAttributeMgr *iface, REFIID iid, LPVOID *ppvOut)
+{
+    DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfDisplayAttributeMgr))
+    {
+        *ppvOut = This;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("unsupported interface: %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI DisplayAttributeMgr_AddRef(ITfDisplayAttributeMgr *iface)
+{
+    DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI DisplayAttributeMgr_Release(ITfDisplayAttributeMgr *iface)
+{
+    DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        DisplayAttributeMgr_Destructor(This);
+    return ret;
+}
+
+/*****************************************************
+ * ITfDisplayAttributeMgr functions
+ *****************************************************/
+
+static HRESULT WINAPI DisplayAttributeMgr_OnUpdateInfo(ITfDisplayAttributeMgr *iface)
+{
+    DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface;
+
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DisplayAttributeMgr_EnumDisplayAttributeInfo(ITfDisplayAttributeMgr *iface, IEnumTfDisplayAttributeInfo **ppEnum)
+{
+    DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface;
+
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DisplayAttributeMgr_GetDisplayAttributeInfo(ITfDisplayAttributeMgr *iface, REFGUID guid, ITfDisplayAttributeInfo **ppInfo, CLSID *pclsidOwner)
+{
+    DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface;
+
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static const ITfDisplayAttributeMgrVtbl DisplayAttributeMgr_DisplayAttributeMgrVtbl =
+{
+    DisplayAttributeMgr_QueryInterface,
+    DisplayAttributeMgr_AddRef,
+    DisplayAttributeMgr_Release,
+
+    DisplayAttributeMgr_OnUpdateInfo,
+    DisplayAttributeMgr_EnumDisplayAttributeInfo,
+    DisplayAttributeMgr_GetDisplayAttributeInfo
+};
+
+HRESULT DisplayAttributeMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
+{
+    DisplayAttributeMgr *This;
+    if (pUnkOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    This = HeapAlloc(GetProcessHeap(),0,sizeof(DisplayAttributeMgr));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    This->DisplayAttributeMgrVtbl= &DisplayAttributeMgr_DisplayAttributeMgrVtbl;
+    This->refCount = 1;
+
+    TRACE("returning %p\n", This);
+    *ppOut = (IUnknown *)This;
+    return S_OK;
+}
index ba4a76d..34e35c4 100644 (file)
@@ -279,8 +279,8 @@ static HRESULT WINAPI InputProcessorProfiles_AddLanguageProfile(
     if (!res)
     {
         DWORD zero = 0x0;
-        RegSetValueExW(fmtkey, desc, 0, REG_SZ, (LPBYTE)pchDesc, cchDesc * sizeof(WCHAR));
-        RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (LPBYTE)pchIconFile, cchFile * sizeof(WCHAR));
+        RegSetValueExW(fmtkey, desc, 0, REG_SZ, (const BYTE*)pchDesc, cchDesc * sizeof(WCHAR));
+        RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (const BYTE*)pchIconFile, cchFile * sizeof(WCHAR));
         RegSetValueExW(fmtkey, icni, 0, REG_DWORD, (LPBYTE)&uIconIndex, sizeof(DWORD));
         if (disposition == REG_CREATED_NEW_KEY)
             RegSetValueExW(fmtkey, szwEnable, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
index 62d1ff2..759fe7e 100644 (file)
@@ -88,6 +88,7 @@ static const struct {
     {&CLSID_TF_InputProcessorProfiles, InputProcessorProfiles_Constructor},
     {&CLSID_TF_CategoryMgr, CategoryMgr_Constructor},
     {&CLSID_TF_LangBarMgr, LangBarMgr_Constructor},
+    {&CLSID_TF_DisplayAttributeMgr, DisplayAttributeMgr_Constructor},
     {NULL, NULL}
 };
 
index de8f52b..cb072f6 100644 (file)
@@ -11,6 +11,7 @@
        <file>categorymgr.c</file>
        <file>compartmentmgr.c</file>
        <file>context.c</file>
+       <file>displayattributemgr.c</file>
        <file>documentmgr.c</file>
        <file>inputprocessor.c</file>
        <file>langbarmgr.c</file>
index 57423e9..9aaaad0 100644 (file)
@@ -41,6 +41,7 @@ extern HRESULT Range_Constructor(ITfContext *context, ITextStoreACP *textstore,
 extern HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut);
 extern HRESULT CompartmentMgr_Destructor(ITfCompartmentMgr *This);
 extern HRESULT LangBarMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
+extern HRESULT DisplayAttributeMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
 
 extern HRESULT Context_Initialize(ITfContext *cxt, ITfDocumentMgr *manager);
 extern HRESULT Context_Uninitialize(ITfContext *cxt);
index 2af1f24..65ebb1d 100644 (file)
@@ -469,6 +469,13 @@ static struct regsvr_coclass const coclass_list[] = {
         "msctf.dll",
         "Apartment"
     },
+    {
+        &CLSID_TF_DisplayAttributeMgr,
+        "TF_DisplayAttributeMgr",
+        NULL,
+        "msctf.dll",
+        "Apartment"
+    },
     { NULL }                   /* list terminator */
 };
 
index e760ac3..12dfef9 100644 (file)
@@ -179,10 +179,10 @@ static DWORD GSM_FormatValidate(const WAVEFORMATEX *wfx)
             WARN("GSM nBlockAlign %u\n", wfx->nBlockAlign);
             return 0;
         }
-        if (((GSM610WAVEFORMAT*)wfx)->wSamplesPerBlock != 320)
+        if (((const GSM610WAVEFORMAT*)wfx)->wSamplesPerBlock != 320)
         {
             WARN("GSM wSamplesPerBlock %u\n",
-                 ((GSM610WAVEFORMAT*)wfx)->wSamplesPerBlock);
+                 ((const GSM610WAVEFORMAT*)wfx)->wSamplesPerBlock);
             return 0;
         }
         if (wfx->nAvgBytesPerSec != wfx->nSamplesPerSec * 65 / 320)
index 4b1bd88..de0c948 100644 (file)
@@ -52,8 +52,11 @@ struct dispex_data_t {
 typedef struct {
     VARIANT var;
     LPWSTR name;
+    DWORD flags;
 } dynamic_prop_t;
 
+#define DYNPROP_DELETED    0x01
+
 typedef struct {
     DispatchEx dispex;
     const IUnknownVtbl *lpIUnknownVtbl;
@@ -245,12 +248,12 @@ static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, const FUN
 
 static int dispid_cmp(const void *p1, const void *p2)
 {
-    return ((func_info_t*)p1)->id - ((func_info_t*)p2)->id;
+    return ((const func_info_t*)p1)->id - ((const func_info_t*)p2)->id;
 }
 
 static int func_name_cmp(const void *p1, const void *p2)
 {
-    return strcmpiW((*(func_info_t**)p1)->name, (*(func_info_t**)p2)->name);
+    return strcmpiW((*(func_info_t* const*)p1)->name, (*(func_info_t* const*)p2)->name);
 }
 
 static dispex_data_t *preprocess_dispex_data(DispatchEx *This)
@@ -319,7 +322,7 @@ static dispex_data_t *preprocess_dispex_data(DispatchEx *This)
 
 static int id_cmp(const void *p1, const void *p2)
 {
-    return *(DISPID*)p1 - *(DISPID*)p2;
+    return *(const DISPID*)p1 - *(const DISPID*)p2;
 }
 
 HRESULT get_dispids(tid_t tid, DWORD *ret_size, DISPID **ret)
@@ -442,7 +445,7 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags
 {
     const BOOL alloc = flags & fdexNameEnsure;
     dispex_dynamic_data_t *data;
-    unsigned i;
+    dynamic_prop_t *prop;
 
     data = get_dynamic_data(This, alloc);
     if(!data) {
@@ -453,9 +456,14 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags
         return DISP_E_UNKNOWNNAME;
     }
 
-    for(i=0; i < data->prop_cnt; i++) {
-        if(flags & fdexNameCaseInsensitive ? !strcmpiW(data->props[i].name, name) : !strcmpW(data->props[i].name, name)) {
-            *ret = data->props+i;
+    for(prop = data->props; prop < data->props+data->prop_cnt; prop++) {
+        if(flags & fdexNameCaseInsensitive ? !strcmpiW(prop->name, name) : !strcmpW(prop->name, name)) {
+            if(prop->flags & DYNPROP_DELETED) {
+                if(!alloc)
+                    return DISP_E_UNKNOWNNAME;
+                prop->flags &= ~DYNPROP_DELETED;
+            }
+            *ret = prop;
             return S_OK;
         }
     }
@@ -481,10 +489,16 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags
         data->buf_size <<= 1;
     }
 
-    data->props[data->prop_cnt].name = heap_strdupW(name);
-    VariantInit(&data->props[data->prop_cnt].var);
-    *ret = data->props + data->prop_cnt++;
+    prop = data->props + data->prop_cnt;
 
+    prop->name = heap_strdupW(name);
+    if(!prop->name)
+        return E_OUTOFMEMORY;
+
+    VariantInit(&prop->var);
+    prop->flags = 0;
+    data->prop_cnt++;
+    *ret = prop;
     return S_OK;
 }
 
@@ -729,6 +743,109 @@ static HRESULT get_builtin_func(dispex_data_t *data, DISPID id, func_info_t **re
     return DISP_E_UNKNOWNNAME;
 }
 
+static HRESULT get_builtin_id(DispatchEx *This, BSTR name, DWORD grfdex, DISPID *ret)
+{
+    dispex_data_t *data;
+    int min, max, n, c;
+
+    data = get_dispex_data(This);
+    if(!data)
+        return E_FAIL;
+
+    min = 0;
+    max = data->func_cnt-1;
+
+    while(min <= max) {
+        n = (min+max)/2;
+
+        c = strcmpiW(data->name_table[n]->name, name);
+        if(!c) {
+            if((grfdex & fdexNameCaseSensitive) && strcmpW(data->name_table[n]->name, name))
+                break;
+
+            *ret = data->name_table[n]->id;
+            return S_OK;
+        }
+
+        if(c > 0)
+            max = n-1;
+        else
+            min = n+1;
+    }
+
+    if(This->data->vtbl && This->data->vtbl->get_dispid) {
+        HRESULT hres;
+
+        hres = This->data->vtbl->get_dispid(This->outer, name, grfdex, ret);
+        if(hres != DISP_E_UNKNOWNNAME)
+            return hres;
+    }
+
+    return DISP_E_UNKNOWNNAME;
+}
+
+static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp,
+        VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
+{
+    dispex_data_t *data;
+    func_info_t *func;
+    HRESULT hres;
+
+    data = get_dispex_data(This);
+    if(!data)
+        return E_FAIL;
+
+    hres = get_builtin_func(data, id, &func);
+    if(id == DISPID_VALUE && hres == DISP_E_UNKNOWNNAME)
+        return dispex_value(This, lcid, flags, dp, res, ei, caller);
+    if(FAILED(hres))
+        return hres;
+
+    if(func->func_disp_idx == -1)
+        hres = typeinfo_invoke(This, func, flags, dp, res, ei);
+    else
+        hres = function_invoke(This, func, flags, dp, res, ei);
+
+    return hres;
+}
+
+HRESULT remove_prop(DispatchEx *This, BSTR name, VARIANT_BOOL *success)
+{
+    dynamic_prop_t *prop;
+    DISPID id;
+    HRESULT hres;
+
+    hres = get_builtin_id(This, name, 0, &id);
+    if(hres == S_OK) {
+        DISPID named_id = DISPID_PROPERTYPUT;
+        VARIANT var;
+        DISPPARAMS dp = {&var,&named_id,1,1};
+        EXCEPINFO ei;
+
+        V_VT(&var) = VT_EMPTY;
+        memset(&ei, 0, sizeof(ei));
+        hres = invoke_builtin_prop(This, id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
+        if(FAILED(hres))
+            return hres;
+
+        *success = VARIANT_TRUE;
+        return S_OK;
+    }
+
+    hres = get_dynamic_prop(This, name, 0, &prop);
+    if(FAILED(hres)) {
+        if(hres != DISP_E_UNKNOWNNAME)
+            return hres;
+        *success = VARIANT_FALSE;
+        return S_OK;
+    }
+
+    VariantClear(&prop->var);
+    prop->flags |= DYNPROP_DELETED;
+    *success = VARIANT_TRUE;
+    return S_OK;
+}
+
 #define DISPATCHEX_THIS(iface) DEFINE_THIS(DispatchEx, IDispatchEx, iface)
 
 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
@@ -815,8 +932,6 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
 {
     DispatchEx *This = DISPATCHEX_THIS(iface);
     dynamic_prop_t *dprop;
-    dispex_data_t *data;
-    int min, max, n, c;
     HRESULT hres;
 
     TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
@@ -824,38 +939,9 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
     if(grfdex & ~(fdexNameCaseSensitive|fdexNameCaseInsensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK))
         FIXME("Unsupported grfdex %x\n", grfdex);
 
-    data = get_dispex_data(This);
-    if(!data)
-        return E_FAIL;
-
-    min = 0;
-    max = data->func_cnt-1;
-
-    while(min <= max) {
-        n = (min+max)/2;
-
-        c = strcmpiW(data->name_table[n]->name, bstrName);
-        if(!c) {
-            if((grfdex & fdexNameCaseSensitive) && strcmpW(data->name_table[n]->name, bstrName))
-                break;
-
-            *pid = data->name_table[n]->id;
-            return S_OK;
-        }
-
-        if(c > 0)
-            max = n-1;
-        else
-            min = n+1;
-    }
-
-    if(This->data->vtbl && This->data->vtbl->get_dispid) {
-        HRESULT hres;
-
-        hres = This->data->vtbl->get_dispid(This->outer, bstrName, grfdex, pid);
-        if(hres != DISP_E_UNKNOWNNAME)
-            return hres;
-    }
+    hres = get_builtin_id(This, bstrName, grfdex, pid);
+    if(hres != DISP_E_UNKNOWNNAME)
+        return hres;
 
     hres = get_dynamic_prop(This, bstrName, grfdex, &dprop);
     if(FAILED(hres))
@@ -869,8 +955,6 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
 {
     DispatchEx *This = DISPATCHEX_THIS(iface);
-    dispex_data_t *data;
-    func_info_t *func;
     HRESULT hres;
 
     TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
@@ -893,12 +977,12 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
 
     if(is_dynamic_dispid(id)) {
         DWORD idx = id - DISPID_DYNPROP_0;
-        VARIANT *var;
+        dynamic_prop_t *prop;
 
         if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx)
             return DISP_E_UNKNOWNNAME;
 
-        var = &This->dynamic_data->props[idx].var;
+        prop = This->dynamic_data->props+idx;
 
         switch(wFlags) {
         case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
@@ -909,8 +993,8 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
             DISPPARAMS dp = {NULL, &named_arg, 0, 1};
             IDispatchEx *dispex;
 
-            if(V_VT(var) != VT_DISPATCH) {
-                FIXME("invoke vt %d\n", V_VT(var));
+            if(V_VT(&prop->var) != VT_DISPATCH) {
+                FIXME("invoke %s\n", debugstr_variant(&prop->var));
                 return E_NOTIMPL;
             }
 
@@ -929,14 +1013,14 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
             V_VT(dp.rgvarg) = VT_DISPATCH;
             V_DISPATCH(dp.rgvarg) = (IDispatch*)DISPATCHEX(This);
 
-            hres = IDispatch_QueryInterface(V_DISPATCH(var), &IID_IDispatchEx, (void**)&dispex);
+            hres = IDispatch_QueryInterface(V_DISPATCH(&prop->var), &IID_IDispatchEx, (void**)&dispex);
             TRACE("%s call\n", debugstr_w(This->dynamic_data->props[idx].name));
             if(SUCCEEDED(hres)) {
                 hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, lcid, wFlags, &dp, pvarRes, pei, pspCaller);
                 IDispatchEx_Release(dispex);
             }else {
                 ULONG err = 0;
-                hres = IDispatch_Invoke(V_DISPATCH(var), DISPID_VALUE, &IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &err);
+                hres = IDispatch_Invoke(V_DISPATCH(&prop->var), DISPID_VALUE, &IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &err);
             }
             TRACE("%s ret %08x\n", debugstr_w(This->dynamic_data->props[idx].name), hres);
 
@@ -944,7 +1028,9 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
             return hres;
         }
         case DISPATCH_PROPERTYGET:
-            return VariantCopy(pvarRes, var);
+            if(prop->flags & DYNPROP_DELETED)
+                return DISP_E_UNKNOWNNAME;
+            return VariantCopy(pvarRes, &prop->var);
         case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF:
         case DISPATCH_PROPERTYPUT:
             if(pdp->cArgs != 1 || (pdp->cNamedArgs == 1 && *pdp->rgdispidNamedArgs != DISPID_PROPERTYPUT)
@@ -954,30 +1040,20 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
             }
 
             TRACE("put %s\n", debugstr_variant(pdp->rgvarg));
-            VariantClear(var);
-            return VariantCopy(var, pdp->rgvarg);
+            VariantClear(&prop->var);
+            hres = VariantCopy(&prop->var, pdp->rgvarg);
+            if(FAILED(hres))
+                return hres;
+
+            prop->flags &= ~DYNPROP_DELETED;
+            return S_OK;
         default:
             FIXME("unhandled wFlags %x\n", wFlags);
             return E_NOTIMPL;
         }
     }
 
-    data = get_dispex_data(This);
-    if(!data)
-        return E_FAIL;
-
-    hres = get_builtin_func(data, id, &func);
-    if(id == DISPID_VALUE && hres == DISP_E_UNKNOWNNAME)
-        return dispex_value(This, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
-    if(FAILED(hres))
-        return hres;
-
-    if(func->func_disp_idx == -1)
-        hres = typeinfo_invoke(This, func, wFlags, pdp, pvarRes, pei);
-    else
-        hres = function_invoke(This, func, wFlags, pdp, pvarRes, pei);
-
-    return hres;
+    return invoke_builtin_prop(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
 }
 
 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
@@ -1055,12 +1131,14 @@ static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex,
         if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx)
             return DISP_E_UNKNOWNNAME;
 
-        if(idx+1 == This->dynamic_data->prop_cnt) {
+        while(++idx < This->dynamic_data->prop_cnt && This->dynamic_data->props[idx].flags & DYNPROP_DELETED);
+
+        if(idx == This->dynamic_data->prop_cnt) {
             *pid = DISPID_STARTENUM;
             return S_FALSE;
         }
 
-        *pid = id+1;
+        *pid = DISPID_DYNPROP_0+idx;
         return S_OK;
     }
 
index 961bb91..14e7ebb 100644 (file)
@@ -508,7 +508,6 @@ void handle_edit_event(HTMLDocument *This, nsIDOMEvent *event)
 
 void handle_edit_load(HTMLDocument *This)
 {
-    This->doc_obj->nscontainer->reset_focus = GetFocus();
     get_editor_controller(This->doc_obj->nscontainer);
 }
 
index e77c1dc..b0cb791 100644 (file)
@@ -198,8 +198,10 @@ static HRESULT WINAPI HTMLElement_removeAttribute(IHTMLElement *iface, BSTR strA
                                                   LONG lFlags, VARIANT_BOOL *pfSuccess)
 {
     HTMLElement *This = HTMLELEM_THIS(iface);
-    FIXME("(%p)->()\n", This);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(strAttributeName), lFlags, pfSuccess);
+
+    return remove_prop(&This->node.dispex, strAttributeName, pfSuccess);
 }
 
 static HRESULT WINAPI HTMLElement_put_className(IHTMLElement *iface, BSTR v)
index 2aafaa3..5dbea55 100644 (file)
@@ -57,6 +57,26 @@ static void window_set_docnode(HTMLWindow *window, HTMLDocumentNode *doc_node)
         if(doc_node)
             htmldoc_addref(&doc_node->basedoc);
     }
+
+    if(doc_node && window->doc_obj->usermode == EDITMODE) {
+        nsIDOMNSHTMLDocument *nshtmldoc;
+        nsAString mode_str;
+        nsresult nsres;
+
+        static const PRUnichar onW[] = {'o','n',0};
+
+        nsres = nsIDOMHTMLDocument_QueryInterface(doc_node->nsdoc, &IID_nsIDOMNSHTMLDocument, (void**)&nshtmldoc);
+        if(NS_SUCCEEDED(nsres)) {
+            nsAString_Init(&mode_str, onW);
+            nsres = nsIDOMNSHTMLDocument_SetDesignMode(nshtmldoc, &mode_str);
+            nsAString_Finish(&mode_str);
+            nsIDOMNSHTMLDocument_Release(nshtmldoc);
+            if(NS_FAILED(nsres))
+                ERR("SetDesignMode failed: %08x\n", nsres);
+        }else {
+            ERR("Could not get nsIDOMNSHTMLDocument interface: %08x\n", nsres);
+        }
+    }
 }
 
 nsIDOMWindow *get_nsdoc_window(nsIDOMDocument *nsdoc)
index e47c284..4122194 100644 (file)
@@ -60,11 +60,6 @@ static const WCHAR mshtml_keyW[] =
      '\\','W','i','n','e',
      '\\','M','S','H','T','M','L',0};
 
-static const CHAR mshtml_keyA[] =
-    {'S','o','f','t','w','a','r','e',
-    '\\','W','i','n','e',
-    '\\','M','S','H','T','M','L',0};
-
 static HWND install_dialog = NULL;
 static LPWSTR tmp_file_name = NULL;
 static HANDLE tmp_file = INVALID_HANDLE_VALUE;
@@ -230,18 +225,23 @@ static BOOL install_from_unix_file(const char *file_name)
 static BOOL install_from_registered_dir(void)
 {
     char *file_name;
+    HKEY hkey;
     DWORD res, type, size = MAX_PATH;
     BOOL ret;
 
-    file_name = heap_alloc(size+sizeof(GECKO_FILE_NAME));
     /* @@ Wine registry key: HKCU\Software\Wine\MSHTML */
-    res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size);
+    res = RegOpenKeyW(HKEY_CURRENT_USER, mshtml_keyW, &hkey);
+    if(res != ERROR_SUCCESS)
+        return FALSE;
+
+    file_name = heap_alloc(size+sizeof(GECKO_FILE_NAME));
+    res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size);
     if(res == ERROR_MORE_DATA) {
         file_name = heap_realloc(file_name, size+sizeof(GECKO_FILE_NAME));
-        res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size);
+        res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size);
     }
-    
-    if(res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) {
+    RegCloseKey(hkey);
+    if(res != ERROR_SUCCESS || type != REG_SZ) {
         heap_free(file_name);
         return FALSE;
     }
index 228be35..3db8d79 100644 (file)
@@ -38,6 +38,7 @@
 #define NS_ERROR_FAILURE          ((nsresult)0x80004005L)
 #define NS_NOINTERFACE            ((nsresult)0x80004002L)
 #define NS_ERROR_NOT_IMPLEMENTED  ((nsresult)0x80004001L)
+#define NS_ERROR_NOT_AVAILABLE    ((nsresult)0x80040111L)
 #define NS_ERROR_INVALID_ARG      ((nsresult)0x80070057L) 
 #define NS_ERROR_UNEXPECTED       ((nsresult)0x8000ffffL)
 #define NS_ERROR_UNKNOWN_PROTOCOL ((nsresult)0x804b0012L)
@@ -171,6 +172,7 @@ void release_dispex(DispatchEx*);
 BOOL dispex_query_interface(DispatchEx*,REFIID,void**);
 HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**);
 HRESULT get_dispids(tid_t,DWORD*,DISPID**);
+HRESULT remove_prop(DispatchEx*,BSTR,VARIANT_BOOL*);
 
 typedef struct HTMLWindow HTMLWindow;
 typedef struct HTMLDocumentNode HTMLDocumentNode;
@@ -435,8 +437,6 @@ struct NSContainer {
     nsIURIContentListener *content_listener;
 
     HWND hwnd;
-
-    HWND reset_focus; /* hack */
 };
 
 typedef struct nsWineURI nsWineURI;
@@ -461,9 +461,16 @@ typedef struct {
     char *content_type;
     char *charset;
     PRUint32 response_status;
+    struct list response_headers;
     UINT url_scheme;
 } nsChannel;
 
+struct ResponseHeader {
+    struct list entry;
+    WCHAR *header;
+    WCHAR *data;
+};
+
 typedef struct {
     HRESULT (*qi)(HTMLDOMNode*,REFIID,void**);
     void (*destructor)(HTMLDOMNode*);
@@ -836,7 +843,6 @@ void update_title(HTMLDocumentObj*);
 
 /* editor */
 void init_editor(HTMLDocument*);
-void set_ns_editmode(NSContainer*);
 void handle_edit_event(HTMLDocument*,nsIDOMEvent*);
 HRESULT editor_exec_copy(HTMLDocument*,DWORD,VARIANT*,VARIANT*);
 HRESULT editor_exec_cut(HTMLDocument*,DWORD,VARIANT*,VARIANT*);
index cc2aeb3..7a77795 100644 (file)
@@ -62,7 +62,7 @@ typedef struct {
     HRESULT (*stop_binding)(BSCallback*,HRESULT);
     HRESULT (*read_data)(BSCallback*,IStream*);
     HRESULT (*on_progress)(BSCallback*,ULONG,LPCWSTR);
-    HRESULT (*on_response)(BSCallback*,DWORD);
+    HRESULT (*on_response)(BSCallback*,DWORD,LPCWSTR);
 } BSCallbackVtbl;
 
 struct BSCallback {
@@ -493,7 +493,7 @@ static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwR
     TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
           debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
 
-    return This->vtbl->on_response(This, dwResponseCode);
+    return This->vtbl->on_response(This, dwResponseCode, szResponseHeaders);
 }
 
 static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
@@ -825,7 +825,8 @@ static HRESULT BufferBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCWSTR
     return S_OK;
 }
 
-static HRESULT BufferBSC_on_response(BSCallback *bsc, DWORD response_code)
+static HRESULT BufferBSC_on_response(BSCallback *bsc, DWORD response_code,
+        LPCWSTR response_headers)
 {
     return S_OK;
 }
@@ -1099,11 +1100,72 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCW
     return S_OK;
 }
 
-static HRESULT nsChannelBSC_on_response(BSCallback *bsc, DWORD response_code)
+static HRESULT nsChannelBSC_on_response(BSCallback *bsc, DWORD response_code,
+        LPCWSTR response_headers)
 {
     nsChannelBSC *This = NSCHANNELBSC_THIS(bsc);
 
     This->nschannel->response_status = response_code;
+
+    if(response_headers) {
+        const WCHAR *hdr_start, *hdr_end;
+
+        hdr_start = strchrW(response_headers, '\r');
+        while(hdr_start) {
+            const WCHAR *colon;
+            struct ResponseHeader *new_header;
+            int len;
+
+            hdr_start += 2;
+            hdr_end = strchrW(hdr_start, '\r');
+            if(!hdr_end) {
+                WARN("Header doesn't end with CRLF: %s\n", wine_dbgstr_w(hdr_start));
+                break;
+            }
+            if(hdr_end == hdr_start)
+                break;
+
+            for(colon = hdr_start; *colon != ':' && colon != hdr_end; ++colon);
+            if(*colon != ':') {
+                WARN("Header missing colon: %s\n", wine_dbgstr_w(hdr_start));
+                hdr_start = strchrW(hdr_start, '\r');
+                continue;
+            }
+
+            new_header = heap_alloc(sizeof(struct ResponseHeader));
+            if(!new_header)
+                return E_OUTOFMEMORY;
+
+            len = colon - hdr_start;
+            new_header->header = heap_alloc((len + 1) * sizeof(WCHAR));
+            if(!new_header->header) {
+                heap_free(new_header);
+                return E_OUTOFMEMORY;
+            }
+            memcpy(new_header->header, hdr_start, len * sizeof(WCHAR));
+            new_header->header[len] = 0;
+
+            colon++;
+            while(*colon == ' ')
+                colon++;
+
+            len = hdr_end - colon;
+            new_header->data = heap_alloc((len + 1) * sizeof(WCHAR));
+            if(!new_header->data) {
+                heap_free(new_header->header);
+                heap_free(new_header);
+                return E_OUTOFMEMORY;
+            }
+            memcpy(new_header->data, colon, len * sizeof(WCHAR));
+            new_header->data[len] = 0;
+
+            list_add_head(&This->nschannel->response_headers, &new_header->entry);
+            TRACE("Adding header to list: (%s):(%s)\n", wine_dbgstr_w(new_header->header), wine_dbgstr_w(new_header->data));
+
+            hdr_start = strchrW(hdr_start, '\r');
+        }
+    }
+
     return S_OK;
 }
 
index fa8aa41..8a59007 100644 (file)
@@ -80,8 +80,6 @@ static const WCHAR wszNsContainer[] = {'N','s','C','o','n','t','a','i','n','e','
 
 static ATOM nscontainer_class;
 
-#define WM_RESETFOCUS_HACK WM_USER+600
-
 static LRESULT WINAPI nsembed_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     NSContainer *This;
@@ -106,20 +104,13 @@ static LRESULT WINAPI nsembed_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
             WARN("SetSize failed: %08x\n", nsres);
         break;
 
-    case WM_RESETFOCUS_HACK:
-        /*
-         * FIXME
-         * Gecko grabs focus in edit mode and some apps don't like it.
-         * We should somehow prevent grabbing focus.
-         */
-
-        TRACE("WM_RESETFOCUS_HACK\n");
+    case WM_PARENTNOTIFY:
+        TRACE("WM_PARENTNOTIFY %x\n", (unsigned)wParam);
 
-        if(This->reset_focus) {
-            SetFocus(This->reset_focus);
-            This->reset_focus = NULL;
-            if(This->doc)
-                This->doc->focus = FALSE;
+        switch(wParam) {
+        case WM_LBUTTONDOWN:
+        case WM_RBUTTONDOWN:
+            nsIWebBrowserFocus_Activate(This->focus);
         }
     }
 
@@ -776,46 +767,6 @@ void get_editor_controller(NSContainer *This)
     }
 }
 
-void set_ns_editmode(NSContainer *This)
-{
-    nsIEditingSession *editing_session = NULL;
-    nsIURIContentListener *listener = NULL;
-    nsIDOMWindow *dom_window = NULL;
-    nsresult nsres;
-
-    nsres = get_nsinterface((nsISupports*)This->webbrowser, &IID_nsIEditingSession,
-            (void**)&editing_session);
-    if(NS_FAILED(nsres)) {
-        ERR("Could not get nsIEditingSession: %08x\n", nsres);
-        return;
-    }
-
-    nsres = nsIWebBrowser_GetContentDOMWindow(This->webbrowser, &dom_window);
-    if(NS_FAILED(nsres)) {
-        ERR("Could not get content DOM window: %08x\n", nsres);
-        nsIEditingSession_Release(editing_session);
-        return;
-    }
-
-    nsres = nsIEditingSession_MakeWindowEditable(editing_session, dom_window,
-            NULL, FALSE, TRUE, TRUE);
-    nsIEditingSession_Release(editing_session);
-    nsIDOMWindow_Release(dom_window);
-    if(NS_FAILED(nsres)) {
-        ERR("MakeWindowEditable failed: %08x\n", nsres);
-        return;
-    }
-
-    /* MakeWindowEditable changes WebBrowser's parent URI content listener.
-     * It seams to be a bug in Gecko. To workaround it we set our content
-     * listener again and Gecko's one as its parent.
-     */
-    nsIWebBrowser_GetParentURIContentListener(This->webbrowser, &listener);
-    nsIURIContentListener_SetParentContentListener(NSURICL(This), listener);
-    nsIURIContentListener_Release(listener);
-    nsIWebBrowser_SetParentURIContentListener(This->webbrowser, NSURICL(This));
-}
-
 void close_gecko(void)
 {
     TRACE("()\n");
@@ -1316,9 +1267,6 @@ static nsresult NSAPI nsEmbeddingSiteWindow_SetFocus(nsIEmbeddingSiteWindow *ifa
 
     TRACE("(%p)\n", This);
 
-    if(This->reset_focus)
-        PostMessageW(This->hwnd, WM_RESETFOCUS_HACK, 0, 0);
-
     return nsIBaseWindow_SetFocus(This->window);
 }
 
index c491424..3e03149 100644 (file)
@@ -109,11 +109,11 @@ static nsrefcnt NSAPI nsDOMEventListener_Release(nsIDOMEventListener *iface)
     return release_listener(This);
 }
 
-static BOOL is_doc_child_focus(HTMLDocumentObj *doc)
+static BOOL is_doc_child_focus(NSContainer *nscontainer)
 {
     HWND hwnd;
 
-    for(hwnd = GetFocus(); hwnd && hwnd != doc->hwnd; hwnd = GetParent(hwnd));
+    for(hwnd = GetFocus(); hwnd && hwnd != nscontainer->hwnd; hwnd = GetParent(hwnd));
 
     return hwnd != NULL;
 }
@@ -129,7 +129,7 @@ static nsresult NSAPI handle_blur(nsIDOMEventListener *iface, nsIDOMEvent *event
         return NS_ERROR_FAILURE;
     doc_obj = doc->basedoc.doc_obj;
 
-    if(!doc_obj->nscontainer->reset_focus && doc_obj->focus && !is_doc_child_focus(doc_obj)) {
+    if(doc_obj->focus && !is_doc_child_focus(doc_obj->nscontainer)) {
         doc_obj->focus = FALSE;
         notif_focus(doc_obj);
     }
@@ -148,7 +148,7 @@ static nsresult NSAPI handle_focus(nsIDOMEventListener *iface, nsIDOMEvent *even
         return NS_ERROR_FAILURE;
     doc_obj = doc->basedoc.doc_obj;
 
-    if(!doc_obj->nscontainer->reset_focus && !doc_obj->focus) {
+    if(!doc_obj->focus) {
         doc_obj->focus = TRUE;
         notif_focus(doc_obj);
     }
index 88a4e55..0c8e457 100644 (file)
@@ -307,7 +307,7 @@ static void set_uri_window(nsWineURI *This, HTMLWindow *window)
 
 static inline BOOL is_http_channel(nsChannel *This)
 {
-    return This->url_scheme == URL_SCHEME_HTTP || This->url_scheme == URL_SCHEME_HTTP;
+    return This->url_scheme == URL_SCHEME_HTTP || This->url_scheme == URL_SCHEME_HTTPS;
 }
 
 #define NSCHANNEL_THIS(iface) DEFINE_THIS(nsChannel, HttpChannel, iface)
@@ -363,6 +363,8 @@ static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
     LONG ref = InterlockedDecrement(&This->ref);
 
     if(!ref) {
+        struct ResponseHeader *header, *next_hdr;
+
         nsIURI_Release(NSURI(This->uri));
         if(This->owner)
             nsISupports_Release(This->owner);
@@ -376,6 +378,14 @@ static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
             nsIURI_Release(This->original_uri);
         heap_free(This->content_type);
         heap_free(This->charset);
+
+        LIST_FOR_EACH_ENTRY_SAFE(header, next_hdr, &This->response_headers, struct ResponseHeader, entry) {
+            list_remove(&header->entry);
+            heap_free(header->header);
+            heap_free(header->data);
+            heap_free(header);
+        }
+
         heap_free(This);
     }
 
@@ -933,9 +943,9 @@ static nsresult NSAPI nsChannel_SetRequestMethod(nsIHttpChannel *iface,
 {
     nsChannel *This = NSCHANNEL_THIS(iface);
 
-    FIXME("(%p)->(%p)\n", This, aRequestMethod);
+    TRACE("(%p)->(%p): Returning NS_OK\n", This, aRequestMethod);
 
-    return NS_ERROR_NOT_IMPLEMENTED;
+    return NS_OK;
 }
 
 static nsresult NSAPI nsChannel_GetReferrer(nsIHttpChannel *iface, nsIURI **aReferrer)
@@ -1052,19 +1062,48 @@ static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface,
 {
     nsChannel *This = NSCHANNEL_THIS(iface);
 
-    FIXME("(%p)->(%p)\n", This, aRequestSucceeded);
+    TRACE("(%p)->(%p)\n", This, aRequestSucceeded);
 
-    return NS_ERROR_NOT_IMPLEMENTED;
+    if(!This->response_status)
+        return NS_ERROR_NOT_AVAILABLE;
+
+    *aRequestSucceeded = This->response_status/100 == 2;
+
+    return NS_OK;
 }
 
 static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface,
          const nsACString *header, nsACString *_retval)
 {
     nsChannel *This = NSCHANNEL_THIS(iface);
+    const char *header_str;
+    WCHAR *header_wstr;
+    struct ResponseHeader *this_header;
 
-    FIXME("(%p)->(%p %p)\n", This, header, _retval);
+    nsACString_GetData(header, &header_str);
+    TRACE("(%p)->(%p(%s) %p)\n", This, header, header_str, _retval);
 
-    return NS_ERROR_NOT_IMPLEMENTED;
+    header_wstr = heap_strdupAtoW(header_str);
+    if(!header_wstr)
+        return NS_ERROR_UNEXPECTED;
+
+    LIST_FOR_EACH_ENTRY(this_header, &This->response_headers, struct ResponseHeader, entry) {
+        if(!strcmpW(this_header->header, header_wstr)) {
+            char *data = heap_strdupWtoA(this_header->data);
+            if(!data) {
+                heap_free(header_wstr);
+                return NS_ERROR_UNEXPECTED;
+            }
+            nsACString_SetData(_retval, data);
+            heap_free(data);
+            heap_free(header_wstr);
+            return NS_OK;
+        }
+    }
+
+    heap_free(header_wstr);
+
+    return NS_ERROR_NOT_AVAILABLE;
 }
 
 static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface,
@@ -2414,7 +2453,6 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString *
     HTMLWindow *window = NULL;
     nsIURI *uri = NULL;
     LPCWSTR base_wine_url = NULL;
-    BOOL is_wine_uri = FALSE;
     nsresult nsres;
 
     nsACString_GetData(aSpec, &spec);
@@ -2425,10 +2463,8 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString *
     if(is_gecko_special_uri(spec))
         return nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
 
-    if(!strncmp(spec, "wine:", 5)) {
+    if(!strncmp(spec, "wine:", 5))
         spec += 5;
-        is_wine_uri = TRUE;
-    }
 
     if(aBaseURI) {
         PARSEDURLA parsed_url = {sizeof(PARSEDURLA)};
@@ -2473,7 +2509,7 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString *
             set_wine_url(wine_uri, url);
         else
              WARN("CoCombineUrl failed: %08x\n", hres);
-    }else if(is_wine_uri) {
+    }else {
         WCHAR url[INTERNET_MAX_URL_LENGTH];
 
         MultiByteToWideChar(CP_ACP, 0, spec, -1, url, sizeof(url)/sizeof(WCHAR));
@@ -2516,6 +2552,7 @@ static nsresult NSAPI nsIOService_NewChannelFromURI(nsIIOService *iface, nsIURI
     ret->lpIHttpChannelInternalVtbl = &nsHttpChannelInternalVtbl;
     ret->ref = 1;
     ret->uri = wine_uri;
+    list_init(&ret->response_headers);
 
     nsIURI_AddRef(aURI);
     ret->original_uri = aURI;
index b54f064..4d5967a 100644 (file)
@@ -616,9 +616,6 @@ static HRESULT exec_editmode(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in,
             IDocHostUIHandler_HideUI(This->doc_obj->hostui);
     }
 
-    if(This->doc_obj->nscontainer)
-        set_ns_editmode(This->doc_obj->nscontainer);
-
     if(This->doc_obj->ui_active) {
         RECT rcBorderWidths;
 
index 261e959..5c096ed 100644 (file)
@@ -92,7 +92,6 @@ static void activate_gecko(NSContainer *This)
 
     nsIBaseWindow_SetVisibility(This->window, TRUE);
     nsIBaseWindow_SetEnabled(This->window, TRUE);
-    nsIWebBrowserFocus_Activate(This->focus);
 }
 
 void update_doc(HTMLDocument *This, DWORD flags)
@@ -216,6 +215,10 @@ static LRESULT WINAPI serverwnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
         break;
     case WM_TIMER:
         return on_timer(This);
+    case WM_SETFOCUS:
+        TRACE("(%p) WM_SETFOCUS\n", This);
+        nsIWebBrowserFocus_Activate(This->nscontainer->focus);
+        break;
     case WM_MOUSEACTIVATE:
         return MA_ACTIVATE;
     }
@@ -664,6 +667,8 @@ static HRESULT WINAPI OleDocumentView_UIActivate(IOleDocumentView *iface, BOOL f
 
         This->doc_obj->ui_active = TRUE;
     }else {
+        This->doc_obj->focus = FALSE;
+        nsIWebBrowserFocus_Deactivate(This->doc_obj->nscontainer->focus);
         if(This->doc_obj->ui_active) {
             This->doc_obj->ui_active = FALSE;
             if(This->doc_obj->ip_window)
@@ -811,7 +816,7 @@ static HRESULT WINAPI ViewObject_SetAdvise(IViewObjectEx *iface, DWORD aspects,
     TRACE("(%p)->(%d %d %p)\n", This, aspects, advf, pAdvSink);
 
     if(aspects != DVASPECT_CONTENT || advf != ADVF_PRIMEFIRST)
-        FIXME("unsuported arguments\n");
+        FIXME("unsupported arguments\n");
 
     if(This->doc_obj->view_sink)
         IAdviseSink_Release(This->doc_obj->view_sink);
index 73ce075..d844626 100644 (file)
@@ -655,7 +655,7 @@ static HRESULT WINAPI ActiveIMMApp_Deactivate(IActiveIMMApp* This)
 static HRESULT WINAPI ActiveIMMApp_OnDefWindowProc(IActiveIMMApp* This,
         HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
 {
-    FIXME("Stub (%p %x %lx %lx)\n",hWnd,Msg,wParam,lParam);
+    //FIXME("Stub (%p %x %lx %lx)\n",hWnd,Msg,wParam,lParam);
     return E_FAIL;
 }
 
index ff8a036..96b6420 100644 (file)
@@ -1298,30 +1298,23 @@ end_of_mci_open:
         }
 
     case MCI_SEEK:
+    case MCI_STEP:
         {
-            MCI_SEEK_PARMS mci_seek;
-
-            switch (lParam)
-            {
-            case MCIWND_START:
-                lParam = SendMessageW(hWnd, MCIWNDM_GETSTART, 0, 0);
-                break;
-
-            case MCIWND_END:
-                lParam = SendMessageW(hWnd, MCIWNDM_GETEND, 0, 0);
-                break;
-            }
+            MCI_SEEK_PARMS mci_seek; /* Layout is usable as MCI_XYZ_STEP_PARMS */
+            DWORD flags = MCI_STEP == wMsg ? 0 :
+                          MCIWND_START == lParam ? MCI_SEEK_TO_START :
+                          MCIWND_END   == lParam ? MCI_SEEK_TO_END : MCI_TO;
 
             mci_seek.dwTo = lParam;
-            mwi->lasterror = mciSendCommandW(mwi->mci, MCI_SEEK,
-                                             MCI_TO, (DWORD_PTR)&mci_seek);
+            mwi->lasterror = mciSendCommandW(mwi->mci, wMsg,
+                                             flags, (DWORD_PTR)&mci_seek);
             if (mwi->lasterror)
             {
                 MCIWND_notify_error(mwi);
                 return mwi->lasterror;
             }
             /* update window to reflect the state */
-            InvalidateRect(hWnd, NULL, TRUE);
+            else InvalidateRect(hWnd, NULL, TRUE);
             return 0;
         }
 
@@ -1364,15 +1357,9 @@ end_of_mci_open:
         }
 
     case MCI_PAUSE:
-    case MCI_STEP:
     case MCI_STOP:
     case MCI_RESUME:
         mci_generic_command(mwi, wMsg);
-        if (wMsg == MCI_STEP && !mwi->lasterror)
-        {
-            /* update window to reflect the state */
-            InvalidateRect(hWnd, NULL, TRUE);
-        }
         return mwi->lasterror;
 
     case MCI_CONFIGURE:
diff --git a/dll/win32/msvfw32/msvfw32_ros.diff b/dll/win32/msvfw32/msvfw32_ros.diff
deleted file mode 100644 (file)
index 331b478..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-Index: msvideo_private.h
-===================================================================
---- msvideo_private.h  (revision 25690)
-+++ msvideo_private.h  (working copy)
-@@ -19,6 +19,9 @@
- #ifndef __WINE_MSVIDEO_PRIVATE_H
- #define __WINE_MSVIDEO_PRIVATE_H
-+/* Installable Compressor Manager */
-+#define ICVERSION 0x0104
-+
- #define ICM_CHOOSE_COMPRESSOR 1
- #define IDC_COMP_LIST 880
- #define IDS_FULLFRAMES 901
diff --git a/dll/win32/msvfw32/msvideo16.c b/dll/win32/msvfw32/msvideo16.c
deleted file mode 100644 (file)
index c873da5..0000000
+++ /dev/null
@@ -1,916 +0,0 @@
-/*
- * msvideo 16-bit functions
- *
- * Copyright 1998 Marcus Meissner
- * Copyright 2000 Bradley Baetz
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winver.h"
-#include "winnls.h"
-#include "winreg.h"
-#include "winuser.h"
-#include "vfw16.h"
-#include "msvideo_private.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
-
-/* Drivers32 settings */
-#define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
-
-/***********************************************************************
- *             DrawDibOpen             [MSVIDEO.102]
- */
-HDRAWDIB16 VFWAPI DrawDibOpen16(void)
-{
-    return HDRAWDIB_16(DrawDibOpen());
-}
-
-/***********************************************************************
- *             DrawDibClose            [MSVIDEO.103]
- */
-BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd)
-{
-    return DrawDibClose(HDRAWDIB_32(hdd));
-}
-
-/************************************************************************
- *             DrawDibBegin            [MSVIDEO.104]
- */
-BOOL16 VFWAPI DrawDibBegin16(HDRAWDIB16 hdd, HDC16 hdc, INT16 dxDst,
-                            INT16 dyDst, LPBITMAPINFOHEADER lpbi, INT16 dxSrc,
-                            INT16 dySrc, UINT16 wFlags)
-{
-    return DrawDibBegin(HDRAWDIB_32(hdd), HDC_32(hdc), dxDst, dyDst, lpbi,
-                       dxSrc, dySrc, wFlags);
-}
-
-/***********************************************************************
- *             DrawDibEnd              [MSVIDEO.105]
- */
-BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd)
-{
-    return DrawDibEnd(HDRAWDIB_32(hdd));
-}
-
-/**********************************************************************
- *             DrawDibDraw             [MSVIDEO.106]
- */
-BOOL16 VFWAPI DrawDibDraw16(HDRAWDIB16 hdd, HDC16 hdc, INT16 xDst, INT16 yDst,
-                           INT16 dxDst, INT16 dyDst, LPBITMAPINFOHEADER lpbi,
-                           LPVOID lpBits, INT16 xSrc, INT16 ySrc, INT16 dxSrc,
-                           INT16 dySrc, UINT16 wFlags)
-{
-    return DrawDibDraw(HDRAWDIB_32(hdd), HDC_32(hdc), xDst, yDst, dxDst,
-                      dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags);
-}
-
-/***********************************************************************
- *              DrawDibGetPalette       [MSVIDEO.108]
- */
-HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd)
-{
-    return HPALETTE_16(DrawDibGetPalette(HDRAWDIB_32(hdd)));
-}
-
-/***********************************************************************
- *              DrawDibSetPalette       [MSVIDEO.110]
- */
-BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal)
-{
-    return DrawDibSetPalette(HDRAWDIB_32(hdd), HPALETTE_32(hpal));
-}
-
-/***********************************************************************
- *              DrawDibRealize          [MSVIDEO.112]
- */
-UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc,
-                              BOOL16 fBackground)
-{
-    return (UINT16)DrawDibRealize(HDRAWDIB_32(hdd), HDC_32(hdc), fBackground);
-}
-
-/*************************************************************************
- *             DrawDibStart            [MSVIDEO.118]
- */
-BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate)
-{
-    return DrawDibStart(HDRAWDIB_32(hdd), rate);
-}
-
-/*************************************************************************
- *             DrawDibStop             [MSVIDEO.119]
- */
-BOOL16 VFWAPI DrawDibStop16(HDRAWDIB16 hdd)
-{
-    return DrawDibStop(HDRAWDIB_32(hdd));
-}
-
-/***********************************************************************
- *             ICOpen                          [MSVIDEO.203]
- */
-HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode)
-{
-    return HIC_16(ICOpen(fccType, fccHandler, wMode));
-}
-
-/***********************************************************************
- *             ICClose                 [MSVIDEO.204]
- */
-LRESULT WINAPI ICClose16(HIC16 hic)
-{
-    return ICClose(HIC_32(hic));
-}
-
-/***********************************************************************
- *             _ICMessage                      [MSVIDEO.207]
- */
-LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist )
-{
-    LPWORD lpData;
-    SEGPTR segData;
-    LRESULT ret;
-    UINT16 i;
-
-    lpData = HeapAlloc(GetProcessHeap(), 0, cb);
-
-    TRACE("0x%08x, %u, %u, ...)\n", (DWORD) hic, msg, cb);
-
-    for (i = 0; i < cb / sizeof(WORD); i++) 
-    {
-       lpData[i] = VA_ARG16(valist, WORD);
-    }
-
-    segData = MapLS(lpData);
-    ret = ICSendMessage16(hic, msg, segData, (DWORD) cb);
-    UnMapLS(segData);
-    HeapFree(GetProcessHeap(), 0, lpData);
-    return ret;
-}
-
-/***********************************************************************
- *             ICGetInfo                       [MSVIDEO.212]
- */
-LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 * picinfo, DWORD cb)
-{
-    LRESULT ret;
-
-    TRACE("(0x%08x,%p,%d)\n", (DWORD) hic, picinfo, cb);
-    ret = ICSendMessage16(hic, ICM_GETINFO, (DWORD) picinfo, cb);
-    TRACE("    -> 0x%08lx\n", ret);
-    return ret;
-}
-
-/***********************************************************************
- *             ICLocate                        [MSVIDEO.213]
- */
-HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler,
-                       LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut,
-                       WORD wFlags)
-{
-    return HIC_16(ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags));
-}
-
-/***********************************************************************
- *             _ICCompress                     [MSVIDEO.224]
- */
-DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags,
-                          LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData,
-                          LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits,
-                          LPDWORD lpckid, LPDWORD lpdwFlags,
-                          LONG lFrameNum, DWORD dwFrameSize,
-                          DWORD dwQuality, LPBITMAPINFOHEADER lpbiPrev,
-                          LPVOID lpPrev)
-{
-    DWORD ret;
-    ICCOMPRESS iccmp;
-    SEGPTR seg_iccmp;
-    
-    TRACE("(0x%08x,%d,%p,%p,%p,%p,...)\n", (DWORD) hic, dwFlags,
-         lpbiOutput, lpData, lpbiInput, lpBits);
-
-    iccmp.dwFlags = dwFlags;
-
-    iccmp.lpbiOutput = lpbiOutput;
-    iccmp.lpOutput = lpData;
-    iccmp.lpbiInput = lpbiInput;
-    iccmp.lpInput = lpBits;
-
-    iccmp.lpckid = lpckid;
-    iccmp.lpdwFlags = lpdwFlags;
-    iccmp.lFrameNum = lFrameNum;
-    iccmp.dwFrameSize = dwFrameSize;
-    iccmp.dwQuality = dwQuality;
-    iccmp.lpbiPrev = lpbiPrev;
-    iccmp.lpPrev = lpPrev;
-    seg_iccmp = MapLS(&iccmp);
-    ret = ICSendMessage16(hic, ICM_COMPRESS, seg_iccmp, sizeof(ICCOMPRESS));
-    UnMapLS(seg_iccmp);
-    return ret;
-}
-
-/***********************************************************************
- *             _ICDecompress                   [MSVIDEO.230]
- */
-DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags,
-                            LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData,
-                            LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
-{
-    ICDECOMPRESS icd;
-    SEGPTR segptr;
-    DWORD ret;
-
-    TRACE("(0x%08x,%d,%p,%p,%p,%p)\n", (DWORD) hic, dwFlags, lpbiFormat,
-         lpData, lpbi, lpBits);
-
-    icd.dwFlags = dwFlags;
-    icd.lpbiInput = lpbiFormat;
-    icd.lpInput = lpData;
-    icd.lpbiOutput = lpbi;
-    icd.lpOutput = lpBits;
-    icd.ckid = 0;
-    segptr = MapLS(&icd);
-    ret = ICSendMessage16(hic, ICM_DECOMPRESS, segptr, sizeof(ICDECOMPRESS));
-    UnMapLS(segptr);
-    return ret;
-}
-
-/***********************************************************************
- *             _ICDrawBegin            [MSVIDEO.232]
- */
-DWORD VFWAPIV ICDrawBegin16(HIC16 hic,         /* [in] */
-                           DWORD dwFlags,      /* [in] flags */
-                           HPALETTE16 hpal,    /* [in] palette to draw with */
-                           HWND16 hwnd,        /* [in] window to draw to */
-                           HDC16 hdc,          /* [in] HDC to draw to */
-                           INT16 xDst,         /* [in] destination rectangle */
-                           INT16 yDst,         /* [in] */
-                           INT16 dxDst,        /* [in] */
-                           INT16 dyDst,        /* [in] */
-                           LPBITMAPINFOHEADER lpbi,    /* [in] format of frame to draw NOTE: SEGPTR */
-                           INT16 xSrc,         /* [in] source rectangle */
-                           INT16 ySrc,         /* [in] */
-                           INT16 dxSrc,        /* [in] */
-                           INT16 dySrc,        /* [in] */
-                           DWORD dwRate,       /* [in] frames/second = (dwRate/dwScale) */
-                           DWORD dwScale)      /* [in] */
-{
-    DWORD ret;
-    ICDRAWBEGIN16 icdb;
-    SEGPTR seg_icdb;
-
-    TRACE ("(0x%08x,%d,0x%08x,0x%08x,0x%08x,%u,%u,%u,%u,%p,%u,%u,%u,%u,%d,%d)\n",
-          (DWORD) hic, dwFlags, (DWORD) hpal, (DWORD) hwnd, (DWORD) hdc,
-          xDst, yDst, dxDst, dyDst, lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate,
-          dwScale);
-
-    icdb.dwFlags = dwFlags;
-    icdb.hpal = hpal;
-    icdb.hwnd = hwnd;
-    icdb.hdc = hdc;
-    icdb.xDst = xDst;
-    icdb.yDst = yDst;
-    icdb.dxDst = dxDst;
-    icdb.dyDst = dyDst;
-    icdb.lpbi = lpbi;          /* Keep this as SEGPTR for the mapping code to deal with */
-    icdb.xSrc = xSrc;
-    icdb.ySrc = ySrc;
-    icdb.dxSrc = dxSrc;
-    icdb.dySrc = dySrc;
-    icdb.dwRate = dwRate;
-    icdb.dwScale = dwScale;
-    seg_icdb = MapLS(&icdb);
-    ret = (DWORD) ICSendMessage16(hic, ICM_DRAW_BEGIN, seg_icdb,
-                                 sizeof(ICDRAWBEGIN16));
-    UnMapLS(seg_icdb);
-    return ret;
-}
-
-/***********************************************************************
- *             _ICDraw                 [MSVIDEO.234]
- */
-DWORD VFWAPIV ICDraw16(HIC16 hic, DWORD dwFlags,
-                      LPVOID lpFormat, /* [???] NOTE: SEGPTR */
-                      LPVOID lpData,   /* [???] NOTE: SEGPTR */
-                      DWORD cbData, LONG lTime)
-{
-    DWORD ret;
-    ICDRAW icd;
-    SEGPTR seg_icd;
-
-    TRACE("(0x%08x,0x%08x,%p,%p,%d,%d)\n", (DWORD) hic, dwFlags,
-         lpFormat, lpData, cbData, lTime);
-    icd.dwFlags = dwFlags;
-    icd.lpFormat = lpFormat;
-    icd.lpData = lpData;
-    icd.cbData = cbData;
-    icd.lTime = lTime;
-    seg_icd = MapLS(&icd);
-    ret = ICSendMessage16(hic, ICM_DRAW, seg_icd, sizeof(ICDRAW));
-    UnMapLS(seg_icd);
-    return ret;
-}
-
-/***********************************************************************
- *             ICGetDisplayFormat                      [MSVIDEO.239]
- */
-HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn,
-                                 LPBITMAPINFOHEADER lpbiOut, INT16 depth,
-                                 INT16 dx, INT16 dy)
-{
-    return HIC_16(ICGetDisplayFormat(HIC_32(hic), lpbiIn, lpbiOut, depth,
-                                    dx, dy));
-}
-
-#define COPY(x,y) (x->y = x##16->y);
-#define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));
-
-/******************************************************************
- *             MSVIDEO_MapICDEX16To32
- *
- *
- */
-static LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam) 
-{
-    LPVOID ret;
-
-    ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESSEX));
-    ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
-    ret = icdx16;
-
-    COPY(icdx, dwFlags);
-    COPYPTR(icdx, lpbiSrc);
-    COPYPTR(icdx, lpSrc);
-    COPYPTR(icdx, lpbiDst);
-    COPYPTR(icdx, lpDst);
-    COPY(icdx, xDst);
-    COPY(icdx, yDst);
-    COPY(icdx, dxDst);
-    COPY(icdx, dyDst);
-    COPY(icdx, xSrc);
-    COPY(icdx, ySrc);
-    COPY(icdx, dxSrc);
-    COPY(icdx, dySrc);
-
-    *lParam = (DWORD)(icdx);
-    return ret;
-}
-
-/******************************************************************
- *             MSVIDEO_MapMsg16To32
- *
- *
- */
-static LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2)
-{
-    LPVOID ret = 0;
-
-    TRACE("Mapping %d\n", msg);
-
-    switch (msg) 
-    {
-    case DRV_LOAD:
-    case DRV_ENABLE:
-    case DRV_CLOSE:
-    case DRV_DISABLE:
-    case DRV_FREE:
-    case ICM_ABOUT:
-    case ICM_CONFIGURE:
-    case ICM_COMPRESS_END:
-    case ICM_DECOMPRESS_END:
-    case ICM_DECOMPRESSEX_END:
-    case ICM_SETQUALITY:
-    case ICM_DRAW_START_PLAY:
-    case ICM_DRAW_STOP_PLAY:
-    case ICM_DRAW_REALIZE:
-    case ICM_DRAW_RENDERBUFFER:
-    case ICM_DRAW_END:
-        break;
-    case DRV_OPEN:
-    case ICM_GETDEFAULTQUALITY:
-    case ICM_GETQUALITY:
-    case ICM_SETSTATE:
-    case ICM_DRAW_WINDOW:
-    case ICM_GETBUFFERSWANTED:
-        *lParam1 = (DWORD)MapSL(*lParam1);
-        break;
-    case ICM_GETINFO:
-        {
-            ICINFO *ici = HeapAlloc(GetProcessHeap(), 0, sizeof(ICINFO));
-            ICINFO16 *ici16;
-            
-            ici16 = MapSL(*lParam1);
-            ret = ici16;
-            
-            ici->dwSize = sizeof(ICINFO);
-            COPY(ici, fccType);
-            COPY(ici, fccHandler);
-            COPY(ici, dwFlags);
-            COPY(ici, dwVersion);
-            COPY(ici, dwVersionICM);
-            MultiByteToWideChar( CP_ACP, 0, ici16->szName, -1, ici->szName, 16 );
-            MultiByteToWideChar( CP_ACP, 0, ici16->szDescription, -1, ici->szDescription, 128 );
-            MultiByteToWideChar( CP_ACP, 0, ici16->szDriver, -1, ici->szDriver, 128 );
-            *lParam1 = (DWORD)(ici);
-            *lParam2 = sizeof(ICINFO);
-        }
-        break;
-    case ICM_COMPRESS:
-        {
-            ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS));
-            ICCOMPRESS *icc16;
-
-            icc16 = MapSL(*lParam1);
-            ret = icc16;
-
-            COPY(icc, dwFlags);
-            COPYPTR(icc, lpbiOutput);
-            COPYPTR(icc, lpOutput);
-            COPYPTR(icc, lpbiInput);
-            COPYPTR(icc, lpInput);
-            COPYPTR(icc, lpckid);
-            COPYPTR(icc, lpdwFlags);
-            COPY(icc, lFrameNum);
-            COPY(icc, dwFrameSize);
-            COPY(icc, dwQuality);
-            COPYPTR(icc, lpbiPrev);
-            COPYPTR(icc, lpPrev);
-
-            *lParam1 = (DWORD)(icc);
-            *lParam2 = sizeof(ICCOMPRESS);
-        }
-        break;
-    case ICM_DECOMPRESS:
-        {
-            ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESS));
-            ICDECOMPRESS *icd16; /* Same structure except for the pointers */
-
-            icd16 = MapSL(*lParam1);
-            ret = icd16;
-
-            COPY(icd, dwFlags);
-            COPYPTR(icd, lpbiInput);
-            COPYPTR(icd, lpInput);
-            COPYPTR(icd, lpbiOutput);
-            COPYPTR(icd, lpOutput);
-            COPY(icd, ckid);
-
-            *lParam1 = (DWORD)(icd);
-            *lParam2 = sizeof(ICDECOMPRESS);
-        }
-        break;
-    case ICM_COMPRESS_BEGIN:
-    case ICM_COMPRESS_GET_FORMAT:
-    case ICM_COMPRESS_GET_SIZE:
-    case ICM_COMPRESS_QUERY:
-    case ICM_DECOMPRESS_GET_FORMAT:
-    case ICM_DECOMPRESS_QUERY:
-    case ICM_DECOMPRESS_BEGIN:
-    case ICM_DECOMPRESS_SET_PALETTE:
-    case ICM_DECOMPRESS_GET_PALETTE:
-        *lParam1 = (DWORD)MapSL(*lParam1);
-        *lParam2 = (DWORD)MapSL(*lParam2);
-        break;
-    case ICM_DECOMPRESSEX_QUERY:
-        if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
-            WARN("*lParam2 has unknown value %p\n", (ICDECOMPRESSEX16*)*lParam2);
-        /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
-         * This is because of ICMessage(). Special case it?
-         {
-         LPVOID* addr = HeapAlloc(GetProcessHeap(), 0, 2*sizeof(LPVOID));
-         addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
-         if (*lParam2)
-         addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
-         else
-         addr[1] = 0;
-         
-         ret = addr;
-         }
-         break;*/
-    case ICM_DECOMPRESSEX_BEGIN:
-    case ICM_DECOMPRESSEX:
-        ret = MSVIDEO_MapICDEX16To32(lParam1);
-        *lParam2 = sizeof(ICDECOMPRESSEX);
-        break;
-    case ICM_DRAW_BEGIN:
-        {
-            ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWBEGIN));
-            ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
-            ret = icdb16;
-
-            COPY(icdb, dwFlags);
-            icdb->hpal = HPALETTE_32(icdb16->hpal);
-            icdb->hwnd = HWND_32(icdb16->hwnd);
-            icdb->hdc = HDC_32(icdb16->hdc);
-            COPY(icdb, xDst);
-            COPY(icdb, yDst);
-            COPY(icdb, dxDst);
-            COPY(icdb, dyDst);
-            COPYPTR(icdb, lpbi);
-            COPY(icdb, xSrc);
-            COPY(icdb, ySrc);
-            COPY(icdb, dxSrc);
-            COPY(icdb, dySrc);
-            COPY(icdb, dwRate);
-            COPY(icdb, dwScale);
-
-            *lParam1 = (DWORD)(icdb);
-            *lParam2 = sizeof(ICDRAWBEGIN);
-        }
-        break;
-    case ICM_DRAW_SUGGESTFORMAT:
-        {
-            ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWSUGGEST));
-            ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
-
-            ret = icds16;
-
-            COPY(icds, dwFlags);
-            COPYPTR(icds, lpbiIn);
-            COPYPTR(icds, lpbiSuggest);
-            COPY(icds, dxSrc);
-            COPY(icds, dySrc);
-            COPY(icds, dxDst);
-            COPY(icds, dyDst);
-            icds->hicDecompressor = HIC_32(icds16->hicDecompressor);
-
-            *lParam1 = (DWORD)(icds);
-            *lParam2 = sizeof(ICDRAWSUGGEST);
-        }
-        break;
-    case ICM_DRAW:
-        {
-            ICDRAW *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAW));
-            ICDRAW *icd16 = MapSL(*lParam1);
-            ret = icd16;
-
-            COPY(icd, dwFlags);
-            COPYPTR(icd, lpFormat);
-            COPYPTR(icd, lpData);
-            COPY(icd, cbData);
-            COPY(icd, lTime);
-
-            *lParam1 = (DWORD)(icd);
-            *lParam2 = sizeof(ICDRAW);
-        }
-        break;
-    case ICM_DRAW_START:
-    case ICM_DRAW_STOP:
-        break;
-    default:
-        FIXME("%d is not yet handled. Expect a crash.\n", msg);
-    }
-    return ret;
-}
-
-#undef COPY
-#undef COPYPTR
-
-/******************************************************************
- *             MSVIDEO_UnmapMsg16To32
- *
- *
- */
-static void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2)
-{
-    TRACE("Unmapping %d\n", msg);
-
-#define UNCOPY(x, y) (x##16->y = x->y);
-
-    switch (msg) 
-    {
-    case ICM_GETINFO:
-        {
-            ICINFO *ici = (ICINFO*)(*lParam1);
-            ICINFO16 *ici16 = data16;
-
-            UNCOPY(ici, fccType);
-            UNCOPY(ici, fccHandler);
-            UNCOPY(ici, dwFlags);
-            UNCOPY(ici, dwVersion);
-            UNCOPY(ici, dwVersionICM);
-            WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName, 
-                                 sizeof(ici16->szName), NULL, NULL );
-            ici16->szName[sizeof(ici16->szName)-1] = 0;
-            WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription, 
-                                 sizeof(ici16->szDescription), NULL, NULL );
-            ici16->szDescription[sizeof(ici16->szDescription)-1] = 0;
-            /* This just gives garbage for some reason - BB
-               lstrcpynWtoA(ici16->szDriver, ici->szDriver, 128);*/
-
-            HeapFree(GetProcessHeap(), 0, ici);
-        }
-        break;
-    case ICM_DECOMPRESS_QUERY:
-        /*{
-          LPVOID* x = data16;
-          HeapFree(GetProcessHeap(), 0, x[0]);
-          if (x[1])
-          HeapFree(GetProcessHeap(), 0, x[1]);
-          }
-          break;*/
-    case ICM_COMPRESS:
-    case ICM_DECOMPRESS:
-    case ICM_DECOMPRESSEX_QUERY:
-    case ICM_DECOMPRESSEX_BEGIN:
-    case ICM_DECOMPRESSEX:
-    case ICM_DRAW_BEGIN:
-    case ICM_DRAW_SUGGESTFORMAT:
-    case ICM_DRAW:
-        HeapFree(GetProcessHeap(), 0, data16);
-        break;
-    default:
-        ERR("Unmapping unmapped msg %d\n", msg);
-    }
-#undef UNCOPY
-}
-
-/***********************************************************************
- *             ICInfo                          [MSVIDEO.200]
- */
-BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo)
-{
-    BOOL16 ret;
-    LPVOID lpv;
-    DWORD lParam = (DWORD)lpicinfo;
-    DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;
-    
-    /* Use the mapping functions to map the ICINFO structure */
-    lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO, &lParam, &size);
-
-    ret = ICInfo(fccType, fccHandler, (ICINFO*)lParam);
-
-    MSVIDEO_UnmapMsg16To32(ICM_GETINFO, lpv, &lParam, &size);
-
-    return ret;
-}
-
-/******************************************************************
- *             IC_Callback3216
- *
- *
- */
-static  LRESULT CALLBACK  IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD lp1, DWORD lp2)
-{
-    WINE_HIC*   whic;
-    WORD args[8];
-
-    whic = MSVIDEO_GetHicPtr(hic);
-    if (whic)
-    {
-        DWORD ret = 0;
-        switch (msg)
-        {
-        case DRV_OPEN:
-            lp2 = (DWORD)MapLS((void*)lp2);
-            break;
-        }
-        args[7] = HIWORD(hic);
-        args[6] = LOWORD(hic);
-        args[5] = HDRVR_16(whic->hdrv);
-        args[4] = msg;
-        args[3] = HIWORD(lp1);
-        args[2] = LOWORD(lp1);
-        args[1] = HIWORD(lp2);
-        args[0] = LOWORD(lp2);
-        WOWCallback16Ex( whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &ret );
-
-        switch (msg)
-        {
-        case DRV_OPEN:
-            UnMapLS(lp2);
-            break;
-        }
-        return ret;
-    }
-    else return ICERR_BADHANDLE;
-}
-
-/***********************************************************************
- *             ICOpenFunction                  [MSVIDEO.206]
- */
-HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
-{
-    HIC         hic32;
-
-    hic32 = MSVIDEO_OpenFunction(fccType, fccHandler, wMode, 
-                                 (DRIVERPROC)IC_Callback3216, (DWORD)lpfnHandler);
-    return HIC_16(hic32);
-}
-
-/***********************************************************************
- *             ICSendMessage                   [MSVIDEO.205]
- */
-LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) 
-{
-    LRESULT     ret = ICERR_BADHANDLE;
-    WINE_HIC*   whic;
-
-    whic = MSVIDEO_GetHicPtr(HIC_32(hic));
-    if (whic)
-    {
-        /* we've got a 16 bit driver proc... call it directly */
-        if (whic->driverproc16)
-        {
-            WORD args[8];
-            DWORD result;
-
-            /* FIXME: original code was passing hdrv first and hic second */
-            /* but this doesn't match what IC_Callback3216 does */
-            args[7] = HIWORD(hic);
-            args[6] = LOWORD(hic);
-            args[5] = HDRVR_16(whic->hdrv);
-            args[4] = msg;
-            args[3] = HIWORD(lParam1);
-            args[2] = LOWORD(lParam1);
-            args[1] = HIWORD(lParam2);
-            args[0] = LOWORD(lParam2);
-            WOWCallback16Ex( whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &result );
-            ret = result;
-        }
-        else
-        {
-            /* map the message for a 32 bit infrastructure, and pass it along */
-            void*       data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2);
-    
-            ret = MSVIDEO_SendMessage(whic, msg, lParam1, lParam2);
-            if (data16)
-                MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2);
-        }
-    }
-    return ret;
-}
-
-/***********************************************************************
- *             VideoCapDriverDescAndVer        [MSVIDEO.22]
- */
-DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len,
-                                        LPSTR buf2, WORD buf2len)
-{
-    static const char version_info_spec[] = "\\StringFileInfo\\040904E4\\FileDescription";
-    DWORD      verhandle;
-    DWORD      infosize;
-    UINT       subblocklen;
-    char       *s, buf[2048], fn[260];
-    LPBYTE     infobuf;
-    LPVOID     subblock;
-    DWORD      i, cnt = 0, lRet;
-    DWORD      bufLen, fnLen;
-    FILETIME   lastWrite;
-    HKEY       hKey;
-    BOOL        found = FALSE;
-
-    TRACE("(%d,%p,%d,%p,%d)\n", nr, buf1, buf1len, buf2, buf2len);
-    lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &hKey);
-    if (lRet == ERROR_SUCCESS) 
-    {
-       RegQueryInfoKeyA( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);
-       for (i = 0; i < cnt; i++) 
-       {
-           bufLen = sizeof(buf) / sizeof(buf[0]);
-           lRet = RegEnumKeyExA(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite);
-           if (lRet != ERROR_SUCCESS) continue;
-           if (strncasecmp(buf, "vid", 3)) continue;
-           if (nr--) continue;
-           fnLen = sizeof(fn);
-           lRet = RegQueryValueExA(hKey, buf, 0, 0, (LPBYTE)fn, &fnLen);
-           if (lRet == ERROR_SUCCESS) found = TRUE;
-           break;
-       }
-       RegCloseKey( hKey );
-    } 
-
-    /* search system.ini if not found in the registry */
-    if (!found && GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini"))
-    {
-       for (s = buf; *s; s += strlen(s) + 1)
-       {
-           if (strncasecmp(s, "vid", 3)) continue;
-           if (nr--) continue;
-           if (GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini"))
-               found = TRUE;
-           break;
-       }
-    }
-
-    if (!found)
-    {
-        TRACE("No more VID* entries found nr=%d\n", nr);
-        return 20;
-    }
-    infosize = GetFileVersionInfoSizeA(fn, &verhandle);
-    if (!infosize) 
-    {
-        TRACE("%s has no fileversioninfo.\n", fn);
-        return 18;
-    }
-    infobuf = HeapAlloc(GetProcessHeap(), 0, infosize);
-    if (GetFileVersionInfoA(fn, verhandle, infosize, infobuf)) 
-    {
-        /* Yes, two space behind : */
-        /* FIXME: test for buflen */
-        snprintf(buf2, buf2len, "Version:  %d.%d.%d.%d\n",
-                ((WORD*)infobuf)[0x0f],
-                ((WORD*)infobuf)[0x0e],
-                ((WORD*)infobuf)[0x11],
-                ((WORD*)infobuf)[0x10]
-           );
-        TRACE("version of %s is %s\n", fn, buf2);
-    }
-    else 
-    {
-        TRACE("GetFileVersionInfoA failed for %s.\n", fn);
-        lstrcpynA(buf2, fn, buf2len); /* msvideo.dll appears to copy fn*/
-    }
-    /* FIXME: language problem? */
-    if (VerQueryValueA(        infobuf,
-                        version_info_spec,
-                        &subblock,
-                        &subblocklen
-            )) 
-    {
-        UINT copylen = min(subblocklen,buf1len-1);
-        memcpy(buf1, subblock, copylen);
-        buf1[copylen] = '\0';
-        TRACE("VQA returned %s\n", (LPCSTR)subblock);
-    }
-    else 
-    {
-        TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
-        lstrcpynA(buf1, fn, buf1len); /* msvideo.dll appears to copy fn*/
-    }
-    HeapFree(GetProcessHeap(), 0, infobuf);
-    return 0;
-}
-
-/******************************************************************
- *             IC_CallTo16
- *
- *
- */
-static  LRESULT CALLBACK IC_CallTo16(HDRVR hdrv, HIC hic, UINT msg, LPARAM lp1, LPARAM lp2)
-{
-#if 0
-    WINE_HIC*   whic = IC_GetPtr(hic);
-    LRESULT     ret = 0;
-    
-    
-    if (whic->driverproc) 
-    {
-        ret = whic->driverproc(hic, whic->hdrv, msg, lParam1, lParam2);
-    }
-    else
-    {
-        ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2);
-    }
-#else
-    FIXME("No 32=>16 conversion yet\n");
-#endif
-    return 0;
-}
-
-/**************************************************************************
- *                      DllEntryPoint (MSVIDEO.3)
- *
- * MSVIDEO DLL entry point
- *
- */
-BOOL WINAPI VIDEO_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
-                          WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
-{
-    switch (fdwReason) 
-    {
-    case DLL_PROCESS_ATTACH:
-        /* hook in our 16 bit management functions */
-        pFnCallTo16 = IC_CallTo16;
-        break;
-    case DLL_PROCESS_DETACH:
-        /* remove our 16 bit management functions */
-        pFnCallTo16 = NULL;
-        break;
-    case DLL_THREAD_ATTACH:
-    case DLL_THREAD_DETACH:
-        break;
-    }
-    return TRUE;
-}
diff --git a/dll/win32/msvfw32/vfw16.h b/dll/win32/msvfw32/vfw16.h
deleted file mode 100644 (file)
index 5cf9791..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 1999 Marcus Meissner
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifndef __WINE_VFW16_H
-#define __WINE_VFW16_H
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "vfw.h"
-#include "wownt32.h"
-#include "wine/windef16.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif  /* __cplusplus */
-
-typedef HANDLE16 HDRAWDIB16;
-
-#include "pshpack1.h"
-
-typedef struct {
-       DWORD dwSize;
-       DWORD fccType;
-       DWORD fccHandler;
-       DWORD dwFlags;
-       DWORD dwVersion;
-       DWORD dwVersionICM;
-       /*
-        * under Win16, normal chars are used
-        */
-       CHAR szName[16];
-       CHAR szDescription[128];
-       CHAR szDriver[128];
-} ICINFO16;
-
-typedef struct {
-    DWORD              dwFlags;
-    LPBITMAPINFOHEADER lpbiSrc;
-    LPVOID             lpSrc;
-    LPBITMAPINFOHEADER lpbiDst;
-    LPVOID             lpDst;
-
-    INT16              xDst;       /* destination rectangle */
-    INT16              yDst;
-    INT16              dxDst;
-    INT16              dyDst;
-
-    INT16              xSrc;       /* source rectangle */
-    INT16              ySrc;
-    INT16              dxSrc;
-    INT16              dySrc;
-} ICDECOMPRESSEX16;
-
-typedef struct {
-       DWORD           dwFlags;
-       HPALETTE16      hpal;
-       HWND16          hwnd;
-       HDC16           hdc;
-       INT16           xDst;
-       INT16           yDst;
-       INT16           dxDst;
-       INT16           dyDst;
-       LPBITMAPINFOHEADER      lpbi;
-       INT16           xSrc;
-       INT16           ySrc;
-       INT16           dxSrc;
-       INT16           dySrc;
-       DWORD           dwRate;
-       DWORD           dwScale;
-} ICDRAWBEGIN16;
-
-#include "poppack.h"
-
-typedef struct {
-       DWORD dwFlags;
-       LPBITMAPINFOHEADER lpbiIn;
-       LPBITMAPINFOHEADER lpbiSuggest;
-       INT16 dxSrc;
-       INT16 dySrc;
-       INT16 dxDst;
-       INT16 dyDst;
-       HIC16 hicDecompressor;
-} ICDRAWSUGGEST16;
-
-DWORD   VFWAPIV ICDraw16(HIC16,DWORD,LPVOID,LPVOID,DWORD,LONG);
-DWORD   VFWAPIV ICDrawBegin16(HIC16,DWORD,HPALETTE16,HWND16,HDC16,INT16,
-                              INT16,INT16,INT16,LPBITMAPINFOHEADER,
-                              INT16,INT16,INT16,INT16,DWORD,DWORD);
-LRESULT WINAPI  ICClose16(HIC16);
-DWORD   VFWAPIV ICCompress16(HIC16,DWORD,LPBITMAPINFOHEADER,LPVOID,
-                             LPBITMAPINFOHEADER,LPVOID,LPDWORD,
-                             LPDWORD,LONG,DWORD,DWORD,
-                             LPBITMAPINFOHEADER,LPVOID);
-DWORD   VFWAPIV ICDecompress16(HIC16,DWORD,LPBITMAPINFOHEADER,LPVOID,
-                               LPBITMAPINFOHEADER,LPVOID);
-HIC16   VFWAPI  ICGetDisplayFormat16(HIC16,LPBITMAPINFOHEADER,
-                                     LPBITMAPINFOHEADER,INT16,INT16,
-                                     INT16);
-LRESULT VFWAPI  ICGetInfo16(HIC16,ICINFO16 *,DWORD);
-BOOL16  VFWAPI  ICInfo16(DWORD,DWORD,ICINFO16 *);
-HIC16   VFWAPI  ICLocate16(DWORD,DWORD,LPBITMAPINFOHEADER,
-                           LPBITMAPINFOHEADER,WORD);
-LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist );
-HIC16   VFWAPI  ICOpen16(DWORD,DWORD,UINT16);
-HIC16   VFWAPI  ICOpenFunction16(DWORD,DWORD,UINT16,FARPROC16);
-LRESULT VFWAPI  ICSendMessage16(HIC16,UINT16,DWORD,DWORD);
-
-#ifdef __cplusplus
-}
-#endif  /* __cplusplus */
-
-#endif  /* __WINE_VFW16_H */
index 19784eb..68a52c6 100644 (file)
@@ -95,10 +95,18 @@ msvideo1_decode_8bit( int width, int height, const unsigned char *buf, int buf_s
     blocks_high = height / 4;
     total_blocks = blocks_wide * blocks_high;
     block_inc = 4;
+#ifdef ORIGINAL
     row_dec = stride + 4;
+#else
+    row_dec = - (stride - 4); /* such that -row_dec > 0 */
+#endif
 
     for (block_y = blocks_high; block_y > 0; block_y--) {
+#ifdef ORIGINAL
         block_ptr = ((block_y * 4) - 1) * stride;
+#else
+        block_ptr = ((blocks_high - block_y) * 4) * stride;
+#endif
         for (block_x = blocks_wide; block_x > 0; block_x--) {
             /* check if this block should be skipped */
             if (skip_blocks) {
@@ -131,16 +139,7 @@ msvideo1_decode_8bit( int width, int height, const unsigned char *buf, int buf_s
 
                 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
                     for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
-                    {
-#ifdef ORIGINAL
                         pixels[pixel_ptr++] = colors[(flags & 0x1) ^ 1];
-#else
-                        pixels[width*(height-(pixel_ptr/width)-1) + 
-                               pixel_ptr%width] = 
-                               colors[(flags & 0x1) ^ 1];
-                        pixel_ptr++;
-#endif
-                    }
                     pixel_ptr -= row_dec;
                 }
             } else if (byte_b >= 0x90) {
@@ -153,19 +152,9 @@ msvideo1_decode_8bit( int width, int height, const unsigned char *buf, int buf_s
 
                 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
                     for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
-                    {
-#ifdef ORIGINAL
-                        pixels[pixel_ptr++] = 
-                            colors[((pixel_y & 0x2) << 1) + 
+                        pixels[pixel_ptr++] =
+                            colors[((pixel_y & 0x2) << 1) +
                                 (pixel_x & 0x2) + ((flags & 0x1) ^ 1)];
-#else
-                        pixels[width*(height-(pixel_ptr/width)-1) + 
-                               pixel_ptr%width] = 
-                            colors[((pixel_y & 0x2) << 1) + 
-                                (pixel_x & 0x2) + ((flags & 0x1) ^ 1)];
-                        pixel_ptr++;
-#endif
-                    }
                     pixel_ptr -= row_dec;
                 }
             } else {
@@ -174,15 +163,7 @@ msvideo1_decode_8bit( int width, int height, const unsigned char *buf, int buf_s
 
                 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
                     for (pixel_x = 0; pixel_x < 4; pixel_x++)
-                    {
-#ifdef ORIGINAL
                         pixels[pixel_ptr++] = colors[0];
-#else
-                        pixels[width*(height-(pixel_ptr/width)-1) + 
-                               pixel_ptr%width] = colors[0];
-                        pixel_ptr++;
-#endif
-                    }
                     pixel_ptr -= row_dec;
                 }
             }
@@ -218,10 +199,18 @@ msvideo1_decode_16bit( int width, int height, const unsigned char *buf, int buf_
     blocks_high = height / 4;
     total_blocks = blocks_wide * blocks_high;
     block_inc = 4;
+#ifdef ORIGINAL
     row_dec = stride + 4;
+#else
+    row_dec = - (stride - 4); /* such that -row_dec > 0 */
+#endif
 
     for (block_y = blocks_high; block_y > 0; block_y--) {
+#ifdef ORIGINAL
         block_ptr = ((block_y * 4) - 1) * stride;
+#else
+        block_ptr = ((blocks_high - block_y) * 4) * stride;
+#endif
         for (block_x = blocks_wide; block_x > 0; block_x--) {
             /* check if this block should be skipped */
             if (skip_blocks) {
@@ -272,8 +261,8 @@ msvideo1_decode_16bit( int width, int height, const unsigned char *buf, int buf_
 
                     for (pixel_y = 0; pixel_y < 4; pixel_y++) {
                         for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
-                            pixels[pixel_ptr++] = 
-                                colors[((pixel_y & 0x2) << 1) + 
+                            pixels[pixel_ptr++] =
+                                colors[((pixel_y & 0x2) << 1) +
                                     (pixel_x & 0x2) + ((flags & 0x1) ^ 1)];
                         pixel_ptr -= row_dec;
                     }
@@ -408,7 +397,7 @@ static LRESULT CRAM_Decompress( Msvideo1Context *info, ICDECOMPRESS *icd, DWORD
     width  = icd->lpbiInput->biWidth;
     height = icd->lpbiInput->biHeight;
     bit_per_pixel = icd->lpbiInput->biBitCount;
-    stride = width*bit_per_pixel/8;
+    stride = width; /* in bytes or 16bit words */
     sz = icd->lpbiInput->biSizeImage;
 
     if (info->mode_8bit)
@@ -440,7 +429,7 @@ static LRESULT CRAM_DecompressEx( Msvideo1Context *info, ICDECOMPRESSEX *icd, DW
     width  = icd->lpbiSrc->biWidth;
     height = icd->lpbiSrc->biHeight;
     bit_per_pixel = icd->lpbiSrc->biBitCount;
-    stride = width*bit_per_pixel/8;
+    stride = width;
     sz = icd->lpbiSrc->biSizeImage;
 
     if (info->mode_8bit)
@@ -562,6 +551,10 @@ LRESULT WINAPI CRAM_DriverProc( DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg,
                                   (DWORD) lParam2 );
         break;
 
+    case ICM_DECOMPRESS_END:
+        r = ICERR_OK;
+        break;
+
     case ICM_COMPRESS_QUERY:
         FIXME("compression not implemented\n");
         r = ICERR_BADFORMAT;
index 529f9a4..09b71fe 100644 (file)
@@ -196,12 +196,12 @@ static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, DISPID id
 
 static int dispid_cmp(const void *p1, const void *p2)
 {
-    return ((func_info_t*)p1)->id - ((func_info_t*)p2)->id;
+    return ((const func_info_t*)p1)->id - ((const func_info_t*)p2)->id;
 }
 
 static int func_name_cmp(const void *p1, const void *p2)
 {
-    return strcmpiW((*(func_info_t**)p1)->name, (*(func_info_t**)p2)->name);
+    return strcmpiW((*(func_info_t* const*)p1)->name, (*(func_info_t* const*)p2)->name);
 }
 
 static dispex_data_t *preprocess_dispex_data(DispatchEx *This)
index b6caf73..617c008 100644 (file)
@@ -594,7 +594,7 @@ static HRESULT WINAPI domelem_removeAttribute(
     IXMLDOMNamedNodeMap *attr;
     HRESULT hr;
 
-    TRACE("(%p)->(%s)", This, debugstr_w(p));
+    TRACE("(%p)->(%s)\n", This, debugstr_w(p));
 
     hr = IXMLDOMElement_get_attributes(iface, &attr);
     if (hr != S_OK) return hr;
index 9b1eb82..60b0cbd 100644 (file)
@@ -62,7 +62,7 @@ static int wineXmlMatchCallback (char const * filename)
 
 static void *wineXmlOpenCallback (char const * filename)
 {
-    BSTR sFilename = bstr_from_xmlChar( (xmlChar*)filename);
+    BSTR sFilename = bstr_from_xmlChar( (const xmlChar*)filename);
     HANDLE hFile;
 
     TRACE("%s\n", debugstr_w(sFilename));
index ac97681..e263a2a 100644 (file)
@@ -934,8 +934,9 @@ static HRESULT WINAPI xmlnode_get_specified(
     VARIANT_BOOL* isSpecified)
 {
     xmlnode *This = impl_from_IXMLDOMNode( iface );
-    FIXME("(%p)->(%p)\n", This, isSpecified);
-    return E_NOTIMPL;
+    FIXME("(%p)->(%p) stub!\n", This, isSpecified);
+    *isSpecified = VARIANT_TRUE;
+    return S_OK;
 }
 
 static HRESULT WINAPI xmlnode_get_definition(
@@ -1190,8 +1191,8 @@ static HRESULT WINAPI xmlnode_get_dataType(
     switch ( This->node->type )
     {
     case XML_ELEMENT_NODE:
-        pVal = xmlGetNsProp(This->node, (xmlChar*)"dt",
-                            (xmlChar*)"urn:schemas-microsoft-com:datatypes");
+        pVal = xmlGetNsProp(This->node, (const xmlChar*)"dt",
+                            (const xmlChar*)"urn:schemas-microsoft-com:datatypes");
         if (pVal)
         {
             V_VT(dataTypeName) = VT_BSTR;
@@ -1260,20 +1261,20 @@ static HRESULT WINAPI xmlnode_put_dataType(
         xmlAttrPtr pAttr = NULL;
         xmlChar* str = xmlChar_from_wchar(dataTypeName);
 
-        pAttr = xmlHasNsProp(This->node, (xmlChar*)"dt",
-                            (xmlChar*)"urn:schemas-microsoft-com:datatypes");
+        pAttr = xmlHasNsProp(This->node, (const xmlChar*)"dt",
+                            (const xmlChar*)"urn:schemas-microsoft-com:datatypes");
         if (pAttr)
         {
-            pAttr = xmlSetNsProp(This->node, pAttr->ns, (xmlChar*)"dt", str);
+            pAttr = xmlSetNsProp(This->node, pAttr->ns, (const xmlChar*)"dt", str);
 
             hr = S_OK;
         }
         else
         {
-            pNS = xmlNewNs(This->node, (xmlChar*)"urn:schemas-microsoft-com:datatypes", (xmlChar*)"dt");
+            pNS = xmlNewNs(This->node, (const xmlChar*)"urn:schemas-microsoft-com:datatypes", (const xmlChar*)"dt");
             if(pNS)
             {
-                pAttr = xmlNewNsProp(This->node, pNS, (xmlChar*)"dt", str);
+                pAttr = xmlNewNsProp(This->node, pNS, (const xmlChar*)"dt", str);
                 if(pAttr)
                 {
                     xmlAddChild(This->node, (xmlNodePtr)pAttr);
@@ -1294,8 +1295,6 @@ static HRESULT WINAPI xmlnode_put_dataType(
 
 static BSTR EnsureCorrectEOL(BSTR sInput)
 {
-    static const WCHAR SZ_RETURN[] = {'\n',0};
-    static const WCHAR SZ_LINEFEED[] = {'\r',0};
     int nNum = 0;
     BSTR sNew;
     int nLen;
@@ -1305,7 +1304,7 @@ static BSTR EnsureCorrectEOL(BSTR sInput)
     /* Count line endings */
     for(i=0; i < nLen; i++)
     {
-        if(sInput[i] == SZ_RETURN[0])
+        if(sInput[i] == '\n')
             nNum++;
     }
 
@@ -1318,9 +1317,9 @@ static BSTR EnsureCorrectEOL(BSTR sInput)
         sNew = SysAllocStringLen(NULL, nLen + nNum+1);
         for(i=0; i < nLen; i++)
         {
-            if(sInput[i] == SZ_RETURN[0])
+            if(sInput[i] == '\n')
             {
-                sNew[i+nPlace] = SZ_LINEFEED[0];
+                sNew[i+nPlace] = '\r';
                 nPlace++;
             }
             sNew[i+nPlace] = sInput[i];
@@ -1371,7 +1370,7 @@ static BSTR EnsureNoEncoding(BSTR sInput)
 
 /*
  * We are trying to replicate the same behaviour as msxml by converting
- * line endings to \r\n and using idents as \t. The problem is that msxml
+ * line endings to \r\n and using indents as \t. The problem is that msxml
  * only formats nodes that have a line ending. Using libxml we cannot
  * reproduce behaviour exactly.
  *
@@ -1402,7 +1401,7 @@ static HRESULT WINAPI xmlnode_get_xml(
 
             /* Attribute Nodes return a space in front of their name */
             pContent = xmlBufferContent(pXmlBuf);
-            if( ((char*)pContent)[0] == ' ')
+            if( ((const char*)pContent)[0] == ' ')
                 bstrContent = bstr_from_xmlChar(pContent+1);
             else
                 bstrContent = bstr_from_xmlChar(pContent);
@@ -1550,8 +1549,9 @@ static HRESULT WINAPI xmlnode_get_parsed(
     VARIANT_BOOL* isParsed)
 {
     xmlnode *This = impl_from_IXMLDOMNode( iface );
-    FIXME("(%p)->(%p)\n", This, isParsed);
-    return E_NOTIMPL;
+    FIXME("(%p)->(%p) stub!\n", This, isParsed);
+    *isParsed = VARIANT_TRUE;
+    return S_OK;
 }
 
 static HRESULT WINAPI xmlnode_get_namespaceURI(
index 887cb44..5aff39c 100644 (file)
@@ -1,12 +1,17 @@
-LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
+/* FILE:        dll/win32/netcfgx/lang/cs-CZ.rc
+ * TRANSLATOR:  Radek Liska aka Black_Fox (radekliska at gmail dot com)
+ * UPDATED:     2010-03-14
+ * THANKS TO:   potapnik, who translated part of this file
+ */
 
+LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
 
 IDD_TCPIP_BASIC_DLG DIALOGEX DISCARDABLE  0, 0, 246, 228
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
 CAPTION "Obecné nastavení"
 FONT 8, "MS Shell Dlg"
 BEGIN
- LTEXT "Konfigurace IP adres mù\9ee probìhnout automaticky, pokud to Va\9a\9d dovoluje. V opaèném pøípadì kontaktujte správce sítì pro správné nastavení.", -1, 9, 9, 228, 27
+ LTEXT "Konfigurace IP adres mù\9ee probìhnout automaticky, pokud to sí\9d dovoluje. V opaèném pøípadì kontaktujte správce sítì pro správné nastavení.", -1, 9, 9, 228, 27
  CONTROL "Získat IP adresu automaticky", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 14, 43, 210, 12
  GROUPBOX "", -1, 9, 61, 228, 70, BS_GROUPBOX
  CONTROL "&Pou\9eít následující IP adresu:", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON, 14, 59, 105, 12
@@ -28,43 +33,43 @@ END
 
 IDD_TCPIP_ALTCF_DLG DIALOGEX DISCARDABLE  0, 0, 246, 228
 STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION
-CAPTION "Alternate Configuration"
+CAPTION "Alternativní konfigurace"
 FONT 8, "MS Shell Dlg"
 BEGIN
-    LTEXT "If this computer is used on more than one network, enter the alternate IP settings below", -1, 9, 9, 220, 20
-    CONTROL "Au&tomatic private IP address", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 40, 210, 12
+    LTEXT "Pokud je tento poèítaè pou\9eíván ve více ne\9e jedné síti, lze zadat alternativní nastavení ní\9ee", -1, 9, 9, 220, 20
+    CONTROL "Au&tomatická privátní IP adresa", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 40, 210, 12
     GROUPBOX "", -1, 9, 55, 228, 80, BS_GROUPBOX
-    CONTROL "U&ser configured", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 55, 70, 12
-    LTEXT "&IP address:", -1, 14, 75, 135, 8
+    CONTROL "&U\9eivatelské nastavení", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 55, 70, 12
+    LTEXT "&IP adresa:", -1, 14, 75, 135, 8
     CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 150, 75, 80, 12
-    LTEXT "S&ubnet mask:", -1, 14, 95, 135, 8
+    LTEXT "&Maska podsítì:", -1, 14, 95, 135, 8
     CONTROL "",IDC_SUBNETMASK,"SysIPAddress32",WS_TABSTOP, 150, 95, 80, 12    
-    LTEXT "&Default gateway:", -1, 14, 115, 135, 8
+    LTEXT "&Výchozí brána:", -1, 14, 115, 135, 8
     CONTROL "",IDC_DEFGATEWAY,"SysIPAddress32",WS_TABSTOP, 150, 115, 80, 12
-    LTEXT "&Preferred DNS server:", -1, 14, 150, 135, 8
+    LTEXT "&Preferovaný DNS server:", -1, 14, 150, 135, 8
     CONTROL "",IDC_DNS1,"SysIPAddress32",WS_TABSTOP, 150, 150, 80, 12
-    LTEXT "&Alternate DNS server:", -1, 14, 165, 180, 8
+    LTEXT "&Alternativní DNS server:", -1, 14, 165, 180, 8
     CONTROL "",IDC_DNS2,"SysIPAddress32",WS_TABSTOP, 150, 165, 80, 12
 END
 
 IDD_TCPIP_ADVIP_DLG DIALOGEX DISCARDABLE  0, 0, 247, 247
 STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION
-CAPTION "IP Settings"
+CAPTION "IP nastavení"
 FONT 8, "MS Shell Dlg"
 BEGIN
-    GROUPBOX "IP addresses", -1, 5, 5, 240, 90
+    GROUPBOX "IP adresy", -1, 5, 5, 240, 90
     CONTROL "", IDC_IPLIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 15, 15, 210, 55
-    PUSHBUTTON "Add...", IDC_IPADD, 60, 75, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Edit...", IDC_IPMOD, 120, 75, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remove", IDC_IPDEL, 180, 75, 50, 14, WS_TABSTOP
-    GROUPBOX "Default gateways:", -1, 5, 100, 240, 90
+    PUSHBUTTON "Pøidat...", IDC_IPADD, 60, 75, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Upravit...", IDC_IPMOD, 120, 75, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Odebrat", IDC_IPDEL, 180, 75, 50, 14, WS_TABSTOP
+    GROUPBOX "Výchozí brány:", -1, 5, 100, 240, 90
     CONTROL "", IDC_GWLIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 15, 110, 210, 55
-    PUSHBUTTON "Add...", IDC_GWADD, 60, 170, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Edit...", IDC_GWMOD, 120, 170, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remove", IDC_GWDEL, 180, 170, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Pøidat...", IDC_GWADD, 60, 170, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Upravit...", IDC_GWMOD, 120, 170, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Odebrat", IDC_GWDEL, 180, 170, 50, 14, WS_TABSTOP
     GROUPBOX "", -1, 5, 200, 240, 30
-    CHECKBOX "Automatic metric", IDC_AUTOMETRIC, 9, 200, 90, 12, BS_AUTOCHECKBOX | WS_TABSTOP
-    LTEXT "Interface metric:", -1, 15, 215, 90, 12
+    CHECKBOX "Automatická metrika", IDC_AUTOMETRIC, 9, 200, 90, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    LTEXT "Metrika rozhraní:", -1, 15, 215, 90, 12
     EDITTEXT IDC_METRIC, 110, 212, 50, 12, WS_TABSTOP | ES_NUMBER
 END
 
@@ -74,158 +79,158 @@ CAPTION "DNS"
 FONT 8, "MS Shell Dlg"
 BEGIN
     LISTBOX IDC_DNSADDRLIST, 5, 15, 180, 60, LBS_NOTIFY
-    LTEXT "D&NS server addresses, in order of use:", -1, 5, 5, 180, 12
-    PUSHBUTTON "Up", IDC_DNSADDRUP, 190, 30, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Down", IDC_DNSADDRDOWN, 190, 50, 50, 14, WS_TABSTOP
-    PUSHBUTTON "&Add...", IDC_DNSADDRADD, 30, 70, 50, 14, WS_TABSTOP
-    PUSHBUTTON "&Edit...", IDC_DNSADDRMOD, 100, 70, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remo&ve", IDC_DNSADDRDEL, 170, 70, 50, 14, WS_TABSTOP
-    LTEXT "The following three settings are applied to all connections with TCP/IP enabled. For resolution of unqualified names:", -1, 5, 90, 220, 24
-    CONTROL "Append &primary and connection specific DNS suffixes", IDC_PRIMSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 110, 160, 12
-    CHECKBOX "Append parent suffi&xes of the primary DNS suffix", IDC_TOPPRIMSUFFIX, 15, 125, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
-    CONTROL "Append t&hese DNS suffixes(in order):", IDC_SELSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 140, 190, 12
+    LTEXT "&Adresy DNS serverù v poøadí vyu\9eití:", -1, 5, 5, 180, 12
+    PUSHBUTTON "Nahoru", IDC_DNSADDRUP, 190, 30, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Do", IDC_DNSADDRDOWN, 190, 50, 50, 14, WS_TABSTOP
+    PUSHBUTTON "&Pøidat...", IDC_DNSADDRADD, 30, 70, 50, 14, WS_TABSTOP
+    PUSHBUTTON "&Upravit...", IDC_DNSADDRMOD, 100, 70, 50, 14, WS_TABSTOP
+    PUSHBUTTON "&Odebrat", IDC_DNSADDRDEL, 170, 70, 50, 14, WS_TABSTOP
+    LTEXT "Následující tøi nastavení jsou aplikována na v\9aechna pøipojení s povoleným TCP/IP. Pøi rezoluci nekvalifikovaných jmen:", -1, 5, 90, 220, 24
+    CONTROL "Pøipojit p&rimární a pøipojením dané DNS pøípony", IDC_PRIMSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 110, 160, 12
+    CHECKBOX "Pøipojit rodièovské pøípony primární DNS pøípony", IDC_TOPPRIMSUFFIX, 15, 125, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    CONTROL "Pøipojit &tyto DNS pøípony (v tomto poøadí):", IDC_SELSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 140, 190, 12
     LISTBOX IDC_DNSSUFFIXLIST, 5, 155, 180, 60, LBS_NOTIFY
-    PUSHBUTTON "Up", IDC_DNSSUFFIXUP, 190, 170, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Down", IDC_DNSSUFFIXDOWN, 190, 190, 50, 14, WS_TABSTOP
-    PUSHBUTTON "&Add...", IDC_DNSSUFFIXADD, 30, 210, 50, 14, WS_TABSTOP
-    PUSHBUTTON "&Edit...", IDC_DNSSUFFIXMOD, 100, 210, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remo&ve", IDC_DNSSUFFIXDEL, 170, 210, 50, 14, WS_TABSTOP
-    LTEXT "DNS &suffix for this connection:", -1, 5, 225, 110, 14
+    PUSHBUTTON "Nahoru", IDC_DNSSUFFIXUP, 190, 170, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Do", IDC_DNSSUFFIXDOWN, 190, 190, 50, 14, WS_TABSTOP
+    PUSHBUTTON "&Pøidat...", IDC_DNSSUFFIXADD, 30, 210, 50, 14, WS_TABSTOP
+    PUSHBUTTON "&Upravit...", IDC_DNSSUFFIXMOD, 100, 210, 50, 14, WS_TABSTOP
+    PUSHBUTTON "&Odebrat", IDC_DNSSUFFIXDEL, 170, 210, 50, 14, WS_TABSTOP
+    LTEXT "DNS pøípo&na tohoto pøipojení:", -1, 5, 225, 110, 14
     EDITTEXT IDC_SUFFIX, 120, 225, 100, 12, WS_TABSTOP
-    CHECKBOX "&Register this connection's addresses in DNS", IDC_REGSUFFIX, 15, 240, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
-    CHECKBOX "&Use this connection's DNS suffix in DNS registration", IDC_USESUFFIX, 15, 255, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX "Registrovat &adresy tohoto pøipojení v DNS", IDC_REGSUFFIX, 15, 240, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX "P&ou\9eít DNS pøíponu tohoto pøipojení pøi DNS registraci", IDC_USESUFFIX, 15, 255, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
 
 END
 
 IDD_TCPIP_ADVOPT_DLG DIALOGEX DISCARDABLE  0, 0, 247, 247
 STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION
-CAPTION "Options"
+CAPTION "Volby"
 FONT 8, "MS Shell Dlg"
 BEGIN
     LISTBOX IDC_OPTLIST, 5, 30, 230, 70
-    LTEXT "&Optional settings", -1, 5, 15, 130, 12
-    PUSHBUTTON "&Properties", IDC_OPTPROP, 160, 100, 70, 14, WS_TABSTOP
-    GROUPBOX "Description:", -1, 5, 120, 240, 70
+    LTEXT "&Volitelná nastavení", -1, 5, 15, 130, 12
+    PUSHBUTTON "&Podrobnosti", IDC_OPTPROP, 160, 100, 70, 14, WS_TABSTOP
+    GROUPBOX "Popis:", -1, 5, 120, 240, 70
     LTEXT "", IDC_OPTDESC, 15, 130, 220, 33
 END
 
 IDD_TCPIPADDIP_DLG DIALOGEX DISCARDABLE  0, 0, 200, 70
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "TCP/IP Address"
+CAPTION "TCP/IP adresa"
 FONT 8, "MS Shell Dlg"
 BEGIN
     CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 100, 15, 80, 12
-    LTEXT "IP address:", -1, 5, 15, 70, 12
-    LTEXT "Subnet mask:", -1, 5, 30, 70, 12
+    LTEXT "IP adresa:", -1, 5, 15, 70, 12
+    LTEXT "Maska podsítì:", -1, 5, 30, 70, 12
     CONTROL "",IDC_SUBNETMASK,"SysIPAddress32", WS_TABSTOP, 100, 30, 80, 12
-    PUSHBUTTON "", IDC_OK, 50, 50, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
+    PUSHBUTTON "OK", IDC_OK, 50, 50, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Storno", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
 END
 
 IDD_TCPIPGW_DLG DIALOGEX DISCARDABLE  0, 0, 200, 80
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "TCP/IP Gateway Address"
+CAPTION "TCP/IP adresa brány"
 FONT 8, "MS Shell Dlg"
 BEGIN
     CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 100, 15, 80, 12
-    LTEXT "Gateway:", -1, 5, 15, 70, 12
-    CHECKBOX "Automatic metric", IDC_USEMETRIC, 15, 30, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
-    LTEXT "&Metric:", IDC_METRICTXT, 5, 45, 45, 12, WS_DISABLED
+    LTEXT "Brána:", -1, 5, 15, 70, 12
+    CHECKBOX "Automatická metrika", IDC_USEMETRIC, 15, 30, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    LTEXT "&Metrika:", IDC_METRICTXT, 5, 45, 45, 12, WS_DISABLED
     EDITTEXT IDC_METRIC, 100, 45, 50, 12, WS_TABSTOP | ES_NUMBER | WS_DISABLED
     PUSHBUTTON "", IDC_OK, 50, 60, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 110, 60, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Storno", IDCANCEL, 110, 60, 50, 14, WS_TABSTOP
 END
 
 IDD_TCPIPDNS_DLG DIALOGEX DISCARDABLE  0, 0, 200, 80
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "TCP/IP DNS Server"
+CAPTION "TCP/IP DNS server"
 FONT 8, "MS Shell Dlg"
 BEGIN
     CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 5, 25, 80, 12
     LTEXT "DNS server:", -1, 5, 10, 120, 12
     PUSHBUTTON "", IDC_OK, 50, 50, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Storno", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
 END
 
 IDD_TCPIPSUFFIX_DLG DIALOGEX DISCARDABLE  0, 0, 200, 80
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "TCP/IP Domain Suffix"
+CAPTION "TCP/IP doménová pøípona"
 FONT 8, "MS Shell Dlg"
 BEGIN
     EDITTEXT IDC_SUFFIX, 5, 25, 190, 12, WS_TABSTOP
-    LTEXT "Domain suffix:", -1, 5, 10, 120, 12
+    LTEXT "Doménová pøípona:", -1, 5, 10, 120, 12
     PUSHBUTTON "", IDC_OK, 50, 50, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Storno", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP
 END
 
 IDD_TCPIP_FILTER_DLG DIALOGEX DISCARDABLE  0, 0, 305, 220
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "TCP/IP Filtering"
+CAPTION "TCP/IP filtrování"
 FONT 8, "MS Shell Dlg"
 BEGIN
-    CHECKBOX "Enable TCP/IP-Filtering (All adapters)", IDC_USE_FILTER, 15, 5, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX "Zapnout filtrování TCP/IP (v\9aechny adaptéry)", IDC_USE_FILTER, 15, 5, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP
     GROUPBOX "", -1, 5, 30, 90, 150
-    CONTROL "Permit All", IDC_TCP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 30, 70, 12
-    CONTROL "Permit Only", IDC_TCP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 44, 70, 12
+    CONTROL "Povolit v\9ae", IDC_TCP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 30, 70, 12
+    CONTROL "Povolit pouze", IDC_TCP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 44, 70, 12
     CONTROL "", IDC_TCP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 11, 62, 72, 75
-    PUSHBUTTON "Add", IDC_TCP_ADD, 15, 141, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remove", IDC_TCP_DEL, 15, 161, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Pøidat", IDC_TCP_ADD, 15, 141, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Odebrat", IDC_TCP_DEL, 15, 161, 50, 14, WS_TABSTOP
     GROUPBOX "", -1, 105, 30, 90, 150
-    CONTROL "Permit All", IDC_UDP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 30, 70, 12
-    CONTROL "Permit Only", IDC_UDP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 44, 70, 12
+    CONTROL "Povolit v\9ae", IDC_UDP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 30, 70, 12
+    CONTROL "Povolit pouze", IDC_UDP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 44, 70, 12
     CONTROL "", IDC_UDP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 111, 62, 72, 75
-    PUSHBUTTON "Add", IDC_UDP_ADD, 115, 141, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remove", IDC_UDP_DEL, 115, 161, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Pøidat", IDC_UDP_ADD, 115, 141, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Odebrat", IDC_UDP_DEL, 115, 161, 50, 14, WS_TABSTOP
     GROUPBOX "", -1, 205, 30, 90, 150
-    CONTROL "Permit All", IDC_IP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 30, 70, 12
-    CONTROL "Permit Only", IDC_IP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 44, 70, 12
+    CONTROL "Povolit v\9ae", IDC_IP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 30, 70, 12
+    CONTROL "Povolit pouze", IDC_IP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 44, 70, 12
     CONTROL "", IDC_IP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 211, 62, 72, 75
-    PUSHBUTTON "Add", IDC_IP_ADD, 215, 141, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Remove", IDC_IP_DEL, 215, 161, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Pøidat", IDC_IP_ADD, 215, 141, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Odebrat", IDC_IP_DEL, 215, 161, 50, 14, WS_TABSTOP
     PUSHBUTTON "OK", IDC_OK, 150, 190, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 210, 190, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Storno", IDCANCEL, 210, 190, 50, 14, WS_TABSTOP
 END
 
 IDD_TCPIP_PORT_DLG DIALOGEX DISCARDABLE  0, 0, 200, 60
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Add Filter"
+CAPTION "Pøidat filtr"
 FONT 8, "MS Shell Dlg"
 BEGIN
     EDITTEXT IDC_PORT_VAL, 5, 30, 70, 12, WS_TABSTOP | ES_NUMBER
     LTEXT "", IDC_PORT_DESC, 5, 15, 40, 12
     PUSHBUTTON "OK", IDC_OK, 120, 15, 50, 14, WS_TABSTOP
-    PUSHBUTTON "Cancel", IDCANCEL, 120, 30, 50, 14, WS_TABSTOP
+    PUSHBUTTON "Storno", IDCANCEL, 120, 30, 50, 14, WS_TABSTOP
 END
 
 STRINGTABLE
 BEGIN
-       IDS_NET_CONNECT "Network connection"
-       IDS_NO_IPADDR_SET   "The adapter requires at least one IP address. Please enter one."
-       IDS_NO_SUBMASK_SET  "You have entered an address that is missing its subnet mask. Please add a subnet mask."
-       IDS_TCPFILTERDESC   "TCP/IP filtering allows you to control the type of TCP/IP network traffic that reaches your computer."
-       IDS_TCPFILTER       "TCP/IP Filtering"
-       IDS_IPADDR          "IP address"
-       IDS_SUBMASK         "Subnet mask"
-       IDS_GATEWAY         "Gateway"
-       IDS_METRIC          "Metric"
-       IDS_DHCPACTIVE      "DHCP Enabled"
-       IDS_AUTOMATIC       "Automatic"
-       IDS_NOITEMSEL       "You have not selected an item. Select one first."
+       IDS_NET_CONNECT "\9dové pøipojení"
+       IDS_NO_IPADDR_SET   "Adaptér vy\9eaduje zadání alespoò jedné IP adresy."
+       IDS_NO_SUBMASK_SET  "K zadané adrese je nutné doplnit masku podsítì."
+       IDS_TCPFILTERDESC   "TCP/IP filtrování dovoluje kontrolovat typ TCP/IP sí\9dového provozu, který se dostane k tomuto poèítaèi."
+       IDS_TCPFILTER       "TCP/IP filtrování"
+       IDS_IPADDR          "IP adresa"
+       IDS_SUBMASK         "Maska podsítì"
+       IDS_GATEWAY         "Brána"
+       IDS_METRIC          "Metrika"
+       IDS_DHCPACTIVE      "DHCP zapnuto"
+       IDS_AUTOMATIC       "Automaticky"
+       IDS_NOITEMSEL       "Nebyla vybrána \9eádná polo\9eka."
        IDS_TCPIP           "ReactOS-TCP/IP"
-       IDS_ADD             "Add"
+       IDS_ADD             "Pøidat"
        IDS_MOD             "OK"
-       IDS_TCP_PORTS       "TCP Ports"
-       IDS_UDP_PORTS       "UDP Ports"
-       IDS_IP_PROTO        "IP protocols"
-       IDS_PORT_RANGE      "Port numbers must be greater than 0 and less than 65536. Please enter a number within this range."
-       IDS_PROT_RANGE      "Protocol numbers must be greater than 0 and less than 256. Please enter a number within this range."
-       IDS_DUP_NUMBER      "The number you are trying to add is already in the list. Please enter a different number."
-       IDS_DISABLE_FILTER  "Disabling this global TCP/IP setting will affect all adapters."
-       IDS_NO_SUFFIX       "The current setting of search method requires at least one DNS suffix. Please enter one or change the setting."
-       IDS_DOMAIN_SUFFIX   "Domain suffix is not a valid suffix."
-       IDS_DNS_SUFFIX      "The DNS domain name ""%s"" is not a valid DNS name."
-       IDS_DUP_SUFFIX      "The DNS suffix is already on the list."
-       IDS_DUP_IPADDR      "The IP address is already on the list."
-       IDS_DUP_GW          "The default gateway is already on the list."
+       IDS_TCP_PORTS       "TCP porty"
+       IDS_UDP_PORTS       "UDP porty"
+       IDS_IP_PROTO        "IP protokoly"
+       IDS_PORT_RANGE      "Èísla portù musí být zadána vy\9a\9aí ne\9e 0 a ni\9e\9aí ne\9e 65536."
+       IDS_PROT_RANGE      "Èísla protokolù musí být zadána vy\9a\9aí ne\9e 0 a ni\9e\9aí ne\9e 256."
+       IDS_DUP_NUMBER      "Pøidávané èíslo se u\9e nachází v seznamu. Je nutné zadat jiné èíslo."
+       IDS_DISABLE_FILTER  "Vypnutí tohoto globálního nastavení TCP/IP ovlivní v\9aechny adaptéry."
+       IDS_NO_SUFFIX       "Souèasné nastavení metod vyhledávání vy\9eaduje alespoò jednu DNS pøíponu. Je nutné ji zadat nebo zmìnit nastavení."
+       IDS_DOMAIN_SUFFIX   "Zadaná doménová pøípona není platná."
+       IDS_DNS_SUFFIX      "DNS doménové jméno ""%s"" není platné."
+       IDS_DUP_SUFFIX      "DNS pøípona se u\9e nachází v seznamu."
+       IDS_DUP_IPADDR      "IP adresa se u\9e nachází v seznamu."
+       IDS_DUP_GW          "Výchozí brána se u\9e nachází v seznamu."
 END
 
index c9d8a45..ba89dff 100644 (file)
@@ -325,7 +325,6 @@ InstallNetDevice(
        HKEY hLinkageKey = NULL;
        HKEY hConnectionKey = NULL;
        DWORD dwShowIcon, dwLength;
-       SP_DEVINSTALL_PARAMS_W installParams;
 
        /* Get Instance ID */
        if (SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, NULL, 0, &dwLength))
@@ -550,31 +549,6 @@ InstallNetDevice(
                goto cleanup;
        }
 
-       /* HACK: hpoussin, Dec 2005. TCP/IP driver is not able to manage devices
-        * which are installed after its startup. So, we have to reboot to take
-        * this new netcard into account.
-        */
-       /* Should we reboot? */
-       installParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
-       if (!SetupDiGetDeviceInstallParamsW(
-               DeviceInfoSet,
-               DeviceInfoData,
-               &installParams))
-       {
-               rc = GetLastError();
-               DPRINT("SetupDiGetDeviceInstallParams() failed with error 0x%lx\n", rc);
-               goto cleanup;
-       }
-       installParams.Flags |= DI_NEEDRESTART;
-       if (!SetupDiSetDeviceInstallParamsW(
-               DeviceInfoSet,
-               DeviceInfoData,
-               &installParams))
-       {
-               rc = GetLastError();
-               DPRINT("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", rc);
-               goto cleanup;
-       }
        rc = ERROR_SUCCESS;
 
 cleanup:
index 91c57ec..14b9a4a 100644 (file)
@@ -1762,6 +1762,7 @@ StoreDNSSettings(
         pLast = pCur;
         pCur = pCur->Next;
     }
+    This->pCurrentConfig->AutoconfigActive = FALSE;
 }
 
 INT_PTR
@@ -2046,7 +2047,6 @@ TcpipAdvancedDnsDlg(
 
 VOID
 LaunchAdvancedTcpipSettings(
-    HWND hDlg,
     HWND hwndDlg,
     TcpipConfNotifyImpl * This)
 {
@@ -2069,14 +2069,14 @@ LaunchAdvancedTcpipSettings(
     pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW;
     pinfo.u3.phpage = hppages;
     pinfo.nPages = 3;
-    pinfo.hwndParent = hDlg;
+    pinfo.hwndParent = hwndDlg;
     pinfo.pszCaption = szBuffer;
 
     StoreTcpipBasicSettings(hwndDlg, This, FALSE);
     PropertySheetW(&pinfo);
 
     InitializeTcpipBasicDlgCtrls(hwndDlg, This->pCurrentConfig);
-    PropSheet_Changed(hDlg, hwndDlg); 
+    PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 
 }
 
 INT_PTR
@@ -2328,6 +2328,8 @@ InitializeTcpipBasicDlgCtrls(
     else
     {
         SendDlgItemMessageW(hwndDlg, IDC_FIXEDDNS, BM_SETCHECK, BST_CHECKED, 0);
+        EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), TRUE);
+        EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), TRUE);
         if (pCurSettings->Ns)
         {
             SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ns->IpAddress);
@@ -2521,7 +2523,7 @@ TcpipBasicDlg(
                         }
                         break;
                     case IDC_ADVANCED:
-                        LaunchAdvancedTcpipSettings(GetParent(hwndDlg), hwndDlg, (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER));
+                        LaunchAdvancedTcpipSettings(hwndDlg, (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER));
                         break;
                 }
                 break;
@@ -3278,23 +3280,25 @@ INetCfgComponentControl_fnApplyRegistryChanges(
                 RegSetValueExW(hKey, L"DefaultGateway", 0, REG_MULTI_SZ, (LPBYTE)L"", 1 * sizeof(WCHAR));
                 RegSetValueExW(hKey, L"DefaultGatewayMetric", 0, REG_MULTI_SZ, (LPBYTE)L"\0", sizeof(WCHAR) * 2);
             }
+        }
 
-            if (!pCurrentConfig->Ns || pCurrentConfig->AutoconfigActive)
-            {
-                RegSetValueExW(hKey, L"NameServer", 0, REG_SZ, (LPBYTE)L"", 1 * sizeof(WCHAR));
-            }
-            else
+        if (!pCurrentConfig->Ns || pCurrentConfig->AutoconfigActive)
+        {
+            RegSetValueExW(hKey, L"NameServer", 0, REG_SZ, (LPBYTE)L"", 1 * sizeof(WCHAR));
+        }
+        else
+        {
+            pStr = CreateMultiSzString(pCurrentConfig->Ns, IPADDR, &dwSize, TRUE);
+            if(pStr)
             {
-                pStr = CreateMultiSzString(pCurrentConfig->Ns, IPADDR, &dwSize, TRUE);
-                if(pStr)
-                {
-                    RegSetValueExW(hKey, L"NameServer", 0, REG_SZ, (LPBYTE)pStr, dwSize);
-                    RegDeleteValueW(hKey, L"DhcpNameServer");
-                    CoTaskMemFree(pStr);
-                }
+
+                RegSetValueExW(hKey, L"NameServer", 0, REG_SZ, (LPBYTE)pStr, dwSize);
+                RegDeleteValueW(hKey, L"DhcpNameServer");
+                CoTaskMemFree(pStr);
             }
-            RegCloseKey(hKey);
         }
+
+        RegCloseKey(hKey);
     }
     return S_OK;
 }
index 886ad7a..41a04f6 100644 (file)
@@ -1,6 +1,6 @@
 /* FILE:        dll/win32/netid/lang/cs-CZ.rc
  * TRANSLATOR:  Radek Liska aka Black_Fox (radekliska at gmail dot com)
- * UPDATED:     2008-06-26
+ * UPDATED:     2010-03-14
  */
 
 LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
@@ -18,10 +18,9 @@ BEGIN
     LTEXT       "(Implicitní)", IDC_COMPUTERNAME, 98, 68, 144, 11
     LTEXT       "Pracovní skupina:", IDC_WORKGROUPDOMAIN, 6, 84, 64, 9
     LTEXT       "(prázdné)", IDC_WORKGROUPDOMAIN_NAME, 98, 84, 144, 9
-    LTEXT       "Pokud chcete pou\9eít Prùvodce sí\9dovou identifikací k pøipojení se k doménì a vytvoøení místního u\9eivatele, kliknìte na ""Sí\9dová ID"".", IDC_STATIC, 6, 113, 172, 24
-    //musi zustat jako sitova ID, jinak se nevejde na tlacitko!
-    PUSHBUTTON  "&Sí\9dová ID...", IDC_NETWORK_ID, 190, 114, 58, 15
-    LTEXT       "Pokud chcete pøejmenovat tento poèítaè nebo se pøipojit k doménì, kliknìte na ""Zmìnit"".", IDC_STATIC, 6, 149, 170, 17
+    LTEXT       "Kliknutím na ""Sí\9dová ID"" lze pou\9eít Prùvodce sí\9dovou identifikací k pøipojení se k doménì a vytvoøení místního u\9eivatele.", IDC_STATIC, 6, 113, 172, 24
+    PUSHBUTTON  "&Sí\9dová ID...", IDC_NETWORK_ID, 190, 114, 58, 15 //FIXME nic vic nez "sitova ID" se nevejde na tlacitko!
+    LTEXT       "Kliknutím na ""Zmìnit"" lze pøejmenovat tento poèítaè nebo se pøipojit k doménì.", IDC_STATIC, 6, 149, 170, 17
     PUSHBUTTON  "&Zmìnit...",IDC_NETWORK_PROPERTY, 190, 149, 58, 15
     LTEXT       "Poznámka: Identifikaci tohoto poèítaèe mohou zmìnit pouze administrátoøi.", IDC_STATIC, 6, 179, 300, 9
 END
@@ -31,7 +30,7 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_CAPTIO
 CAPTION "Zmìna názvu poèítaèe"
 FONT 8, "MS Shell Dlg"
 BEGIN
-    LTEXT "(message goes here)", 1017, 7, 5, 218, 30
+    LTEXT "(sem patøí zpráva)", 1017, 7, 5, 218, 30
     LTEXT "&Název poèítaèe:", -1, 7, 41, 219, 8
     EDITTEXT 1002, 7, 53, 218, 14, ES_AUTOHSCROLL | ES_OEMCONVERT
     LTEXT "Úplný název poèítaèe:", 1016, 7, 72, 218, 10
@@ -41,7 +40,7 @@ BEGIN
     AUTORADIOBUTTON "&Domény:", 1008, 17, 132, 192, 10, WS_GROUP
     AUTORADIOBUTTON "&Pracovní skupiny:", 1004, 17, 161, 191, 10
     EDITTEXT 116, 28, 144, 181, 14, ES_AUTOHSCROLL | WS_GROUP
-    PUSHBUTTON "Najít moj&i doménu", 1010, 7, 203, 109, 14, NOT WS_VISIBLE | WS_DISABLED
+    PUSHBUTTON "Najít &moji doménu", 1010, 7, 203, 109, 14, NOT WS_VISIBLE | WS_DISABLED
     EDITTEXT 1007, 28, 172, 181, 14, ES_UPPERCASE | ES_AUTOHSCROLL | ES_OEMCONVERT
     DEFPUSHBUTTON "OK", 1, 121, 203, 50, 14, WS_GROUP
     PUSHBUTTON "Storno", 2, 176, 203, 50, 14
@@ -65,7 +64,7 @@ END
 STRINGTABLE
 BEGIN
     1 "* Neznámé *"
-    2 "WORKGROUP"
+    2 "SKUPINA"
     3 "Pøi pokusu o naètení informací o èlenství v doménì nastala následující chyba:"
     4 "Zmìna názvu poèítaèe"
     5 "Pracovní skupina:"
@@ -73,12 +72,12 @@ BEGIN
     22 "Vítejte v pracovní skupinì %1."
     23 "Vítejte v doménì %1."
     24 "Aby se zmìny mohly projevit, musí být poèítaè restartován."
-       25 "You can change the name and the membership of this computer. Changes may affect access to network resources."
+    25 "Lze zmìnit název a èlenství tohoto poèítaèe. Zmìny mohou mít vliv na pøístup k sí\9dovým prostøedkùm."
     1021 "Poznámka: Identifikaci tohoto poèítaèe mohou zmìnit pouze administrátoøi."
     1022 "Poznámka: Identifikace poèítaèe nemù\9ee být zmìnìna z následujících dùvodù:"
-       1030 "The new computer name ""%s"" contains characters which are not allowed. Characters which are not allowed include ` ~ ! @ # $ %% ^ & * ( ) = + _ [ ] { } \\ | ; : ' \" , . < > / and ?"
+    1030 "Nový název poèítaèe ""%s"" obsahuje nepovolené znaky. Mezi nepovolené znaky patøí ` ~ ! @ # $ %% ^ & * ( ) = + _ [ ] { } \\ | ; : ' \" , . < > / ?"
     3210 "&Detaily >>"
     3220 "<< &Detaily"
-       4000 "Information"
-       4001 "Can't set new a computer name!"
+    4000 "Informace"
+    4001 "Nelze nastavit nový název poèítaèe!"
 END
index 26af2b2..a85b379 100644 (file)
@@ -67,13 +67,13 @@ BEGIN
     6 "Dominio:"
     22 "Benvenuto al gruppo di lavoro %1."
     23 "Benvenuto al dominio %1."
-    24 "Il computer deve essre riavviato per rendere operative queste modifiche."
-       25 "You can change the name and the membership of this computer. Changes may affect access to network resources."
+    24 "Il computer deve essere riavviato per rendere operative queste modifiche."
+    25 "Potete modificare il nome e il dominio di questo computer. Le modifiche potrebbero influenzare l'accesso alle risorse di rete."
     1021 "Nota: Solo gli Amministratori possono cambiare l'identificazione di questo computer."
     1022 "Nota: L'identificazione di questo computer non può essere cambiata perchè:"
-       1030 "The new computer name ""%s"" contains characters which are not allowed. Characters which are not allowed include ` ~ ! @ # $ %% ^ & * ( ) = + _ [ ] { } \\ | ; : ' \" , . < > / and ?"
+    1030 "Il nuovo nome del computer ""%s"" contiene dei caratteri non permessi. I caratteri vietati sono `? ~ ! @ # $ %% ^ & * ( ) = + _ [ ] { } \\ | ; : ' \" , . < > / "
     3210 "&Dettagli >>"
     3220 "<< &Dettagli"
-       4000 "Information"
-       4001 "Can't set new a computer name!"
+    4000 "Informazioni"
+    4001 "Impossibile assegnare il nuovo nome del computer!"
 END
index a42b9b5..c47a181 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
  LTEXT "Ñêîðîñò:", -1, 19, 48, 60, 8
  GROUPBOX "Äåéíîñò", -1, 9, 74, 182, 70, BS_GROUPBOX
  RTEXT "Ïðàòåíè", -1, 26, 90, 60, 8
- ICON IDI_NETSTAT, -1, 110, 85, 18, 20
+ ICON "", IDC_NETSTAT, 110, 85, 18, 20
  LTEXT "Ïîëó÷åíè", -1, 149, 90, 37, 8
  LTEXT "Áàéòà:", -1, 17, 115, 32, 8
  RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index db5e3ea..c0818ab 100644 (file)
@@ -16,12 +16,12 @@ BEGIN
     GROUPBOX "Popis", -1, 9, 153, 230, 46, BS_GROUPBOX
     LTEXT "Tak tady bude popis komponenty...", IDC_DESCRIPTION, 15, 165, 217, 28, WS_GROUP
     CHECKBOX "Po pøipojení zobrazit ikonu na hlavním panelu", IDC_SHOWTASKBAR, 9, 206, 230, 12, BS_AUTOCHECKBOX | WS_TABSTOP
-    CHECKBOX "&Notify me when this connection has limited or no connectivity", IDC_NOTIFYNOCONNECTION, 9, 220, 230, 24, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX "&Upozornit, kdy\9e toto pøipojení bude mít omezenou nebo \9eádnou konektivitu", IDC_NOTIFYNOCONNECTION, 9, 220, 230, 24, BS_AUTOCHECKBOX | WS_TABSTOP
 END
 
 IDD_STATUS DIALOGEX DISCARDABLE  0, 0, 200, 280
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "General"
+CAPTION "Obecné nastavení"
 FONT 8, "MS Shell Dlg"
 BEGIN
 END
@@ -37,7 +37,7 @@ BEGIN
     LTEXT "Rychlost:", -1, 19, 48, 60, 8
     GROUPBOX "Aktivita", -1, 9, 74, 182, 70, BS_GROUPBOX
     RTEXT "Odesláno", -1, 26, 90, 60, 8
-    ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+    ICON "", IDC_NETSTAT, 110, 85, 32, 32
     LTEXT "Pøijato", -1, 149, 90, 37, 8
     LTEXT "Bytù:", -1, 17, 115, 32, 8
     RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
@@ -65,62 +65,62 @@ BEGIN
     RTEXT "000.000.000.000", IDC_DETAILSSUBNET, 122, 48, 80, 8
     RTEXT "", IDC_DETAILSGATEWAY, 122, 62, 80, 8
 
-    PUSHBUTTON "&Detaily...", IDC_DETAILS, 22, 76, 62, 14
+    PUSHBUTTON "&Podrobnosti...", IDC_DETAILS, 22, 76, 62, 14
 END
 
 IDD_LAN_NETSTATUSDETAILS DIALOGEX DISCARDABLE  0, 0, 200,200
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
-CAPTION "Network Connection Details"
+CAPTION "Podrobnosti sí\9dového pøipojení"
 FONT 8, "MS Shell Dlg"
 BEGIN
-    LTEXT "Network Connection &Details:", -1, 15, 9, 170, 12
+    LTEXT "&Podrobnosti sí\9dového pøipojení:", -1, 15, 9, 170, 12
     CONTROL "", IDC_DETAILS, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 15, 25, 170, 130
-    PUSHBUTTON "&Close", IDC_CLOSE, 125, 165, 62, 14
+    PUSHBUTTON "&zavøít", IDC_CLOSE, 125, 165, 62, 14
 END
 
 STRINGTABLE DISCARDABLE
 BEGIN
-    IDS_PHYSICAL_ADDRESS        "Physical Address"
-    IDS_IP_ADDRESS              "IP Address"
-    IDS_SUBNET_MASK             "Subnet Mask"
-    IDS_DEF_GATEWAY             "Default Gateway"
-    IDS_DHCP_SERVER             "DHCP Server"
-    IDS_LEASE_OBTAINED          "Lease Obtained"
-    IDS_LEASE_EXPIRES           "Lease Expires"
-    IDS_DNS_SERVERS             "DNS Servers"
-    IDS_WINS_SERVERS            "WINS Servers"
-    IDS_PROPERTY                "Property"
-    IDS_VALUE                   "Value"
-    IDS_NETWORKCONNECTION       "Network Connection"
-    IDS_SHV_COLUMN_NAME         "Name"
-    IDS_SHV_COLUMN_TYPE         "Type"
+    IDS_PHYSICAL_ADDRESS        "Fyzická adresa"
+    IDS_IP_ADDRESS              "IP Adresa"
+    IDS_SUBNET_MASK             "Maska podsítì"
+    IDS_DEF_GATEWAY             "Výchozí brána"
+    IDS_DHCP_SERVER             "DHCP server"
+    IDS_LEASE_OBTAINED          "Zapùjèeno"
+    IDS_LEASE_EXPIRES           "Zapùjèení vypr\9aí"
+    IDS_DNS_SERVERS             "DNS servery"
+    IDS_WINS_SERVERS            "WINS servery"
+    IDS_PROPERTY                "Vlastnost"
+    IDS_VALUE                   "Hodnota"
+    IDS_NETWORKCONNECTION       "\9dová pøipojení"
+    IDS_SHV_COLUMN_NAME         "Název"
+    IDS_SHV_COLUMN_TYPE         "Typ"
     IDS_SHV_COLUMN_STATE        "Status"
-    IDS_SHV_COLUMN_DEVNAME      "Device Name"
-    IDS_SHV_COLUMN_PHONE        "Phone # or Host Address"
-    IDS_SHV_COLUMN_OWNER        "Owner"
-    IDS_TYPE_ETHERNET           "LAN or High-Speed Internet"
-    IDS_STATUS_NON_OPERATIONAL  "Disabled"
-    IDS_STATUS_UNREACHABLE      "Not Connected"
-    IDS_STATUS_DISCONNECTED     "Network cable unplugged"
-    IDS_STATUS_CONNECTING       "Acquiring network address"
-    IDS_STATUS_CONNECTED        "Connected"
-    IDS_STATUS_OPERATIONAL      "Connected"
+    IDS_SHV_COLUMN_DEVNAME      "Název zaøízení"
+    IDS_SHV_COLUMN_PHONE        "Telefonní èíslo nebo adresa hostitele"
+    IDS_SHV_COLUMN_OWNER        "Vlastník"
+    IDS_TYPE_ETHERNET           "LAN nebo vysokorychlostní internet"
+    IDS_STATUS_NON_OPERATIONAL  "Vypnuto"
+    IDS_STATUS_UNREACHABLE      "Nepøipojeno"
+    IDS_STATUS_DISCONNECTED     "\9dový kabel byl odpojen"
+    IDS_STATUS_CONNECTING       "Získávám sí\9dovou adresu"
+    IDS_STATUS_CONNECTED        "Pøipojeno"
+    IDS_STATUS_OPERATIONAL      "Pøipojeno"
 
-    IDS_NET_ACTIVATE            "Enable"
-    IDS_NET_DEACTIVATE          "Disable"
+    IDS_NET_ACTIVATE            "Zapnout"
+    IDS_NET_DEACTIVATE          "Vypnout"
     IDS_NET_STATUS              "Status"
-    IDS_NET_REPAIR              "Repair"
-    IDS_NET_CREATELINK          "Create Shortcut"
-    IDS_NET_DELETE              "Delete"
-    IDS_NET_RENAME              "Rename"
-    IDS_NET_PROPERTIES          "Properties"
+    IDS_NET_REPAIR              "Opravit"
+    IDS_NET_CREATELINK          "Vytvoøit zástupce"
+    IDS_NET_DELETE              "Smazat"
+    IDS_NET_RENAME              "Pøejmenovat"
+    IDS_NET_PROPERTIES          "Vlasnosti"
 
     IDS_FORMAT_BIT              "%u Bit/s"
     IDS_FORMAT_KBIT             "%u KBit/s"
     IDS_FORMAT_MBIT             "%u MBit/s"
     IDS_FORMAT_GBIT             "%u GBit/s"
-    IDS_DURATION_DAY            "%d Day %s"
-    IDS_DURATION_DAYS           "%d Days %s"
+    IDS_DURATION_DAY            "%d Den %s"
+    IDS_DURATION_DAYS           "%d D %s"
     IDS_ASSIGNED_DHCP           "Pøiøazeno DHCP"
     IDS_ASSIGNED_MANUAL         "Ruènì nastaveno"
 END
index 682914a..d23e9c5 100644 (file)
@@ -36,7 +36,7 @@ BEGIN
  LTEXT "Hastighed:", -1, 19, 48, 60, 8
  GROUPBOX "Netværks Aktivitet", -1, 9, 74, 182, 70, BS_GROUPBOX
  RTEXT "Sendt", -1, 26, 90, 60, 8
- ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+ ICON "", IDC_NETSTAT, 110, 85, 32, 32
  LTEXT " Modtaget", -1, 149, 90, 37, 8
  LTEXT "Bytes:", -1, 73, 115, 44, 8
  RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index 3192b29..de2c06b 100644 (file)
@@ -16,7 +16,7 @@ BEGIN
        GROUPBOX "Beschreibung", -1, 9, 153, 230, 46, BS_GROUPBOX
        LTEXT "Hier wird die Beschreibung des Elementes stehen....", IDC_DESCRIPTION, 15, 165, 217, 28, WS_GROUP
        CHECKBOX "&Symbol bei Verbindung im Infobereich anzeigen", IDC_SHOWTASKBAR, 9, 206, 230, 12, BS_AUTOCHECKBOX | WS_TABSTOP
-        CHECKBOX "&Benachrichtigen, wenn diese Verbindung eingeschränkte oder\nkeine Konnektivität besitzt", IDC_NOTIFYNOCONNECTION, 9, 220, 230, 24, BS_AUTOCHECKBOX | WS_TABSTOP
+       CHECKBOX "&Benachrichtigen, wenn diese Verbindung eingeschränkte oder keine Konnektivität besitzt", IDC_NOTIFYNOCONNECTION, 9, 220, 230, 24, BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP
 END
 
 IDD_STATUS DIALOGEX DISCARDABLE  0, 0, 200, 280
@@ -54,16 +54,16 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
 CAPTION "Netzwerkunterstützung"
 FONT 8, "MS Shell Dlg"
 BEGIN
-       GROUPBOX "Verbindungsstatus", -1, 9, 8, 200, 88, BS_GROUPBOX
+       GROUPBOX "Verbindungsstatus", -1, 9, 8, 182, 88, BS_GROUPBOX
        LTEXT "Adresstyp:", -1, 22, 20, 80, 8
        LTEXT "IP-Adresse:", -1, 22, 34, 80, 8
        LTEXT "Subnetzmaske:", -1, 22, 48, 80, 8
        LTEXT "Standardgateway:", -1, 22, 62, 80, 8
 
-       RTEXT "Nicht verfügbar", IDC_DETAILSTYPE, 122, 20, 80, 8
-       RTEXT "000.000.000.000", IDC_DETAILSIP, 122, 34, 80, 8
-       RTEXT "000.000.000.000", IDC_DETAILSSUBNET, 122, 48, 80, 8
-       RTEXT "", IDC_DETAILSGATEWAY, 122, 62, 80, 8
+       RTEXT "Nicht verfügbar", IDC_DETAILSTYPE, 100, 20, 80, 8
+       RTEXT "000.000.000.000", IDC_DETAILSIP, 100, 34, 80, 8
+       RTEXT "000.000.000.000", IDC_DETAILSSUBNET, 100, 48, 80, 8
+       RTEXT "", IDC_DETAILSGATEWAY, 100, 62, 80, 8
 
        PUSHBUTTON "&Details...", IDC_DETAILS, 22, 76, 62, 14
 END
index 9df47c3..c0eacd6 100644 (file)
@@ -36,7 +36,7 @@ BEGIN
  LTEXT "Ôá÷ýôçôá:", -1, 19, 48, 60, 8
  GROUPBOX "Åíåñãçôéêüôçôá", -1, 9, 74, 182, 70, BS_GROUPBOX
  RTEXT "ÁðåóôÜëëçóáí", -1, 26, 90, 60, 8
- ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+ ICON "", IDC_NETSTAT, 110, 85, 32, 32
  LTEXT "ÅëÞöèçóáí", -1, 149, 90, 37, 8
  LTEXT "Bytes:", -1, 17, 115, 32, 8
  RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index 350e73c..a9d17bc 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
     LTEXT "Speed:", -1, 19, 48, 60, 8
     GROUPBOX "Activity", -1, 9, 74, 182, 70, BS_GROUPBOX
     RTEXT "Sent", -1, 26, 90, 60, 8
-    ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+    ICON "", IDC_NETSTAT, 110, 85, 32, 32
     LTEXT "Received", -1, 149, 90, 37, 8
     LTEXT "Bytes:", -1, 17, 115, 32, 8
     RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index 284425b..bc6cedc 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
     LTEXT "Velocidad:", -1, 19, 48, 60, 8
     GROUPBOX "Actividad ", -1, 9, 74, 182, 70, BS_GROUPBOX
     RTEXT "Enviados", -1, 26, 90, 60, 8
-    ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+    ICON "", IDC_NETSTAT, 110, 85, 32, 32
     LTEXT "Recibidos", -1, 149, 90, 37, 8
     LTEXT "Paquetes:", -1, 17, 115, 32, 8
     RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index 6ca04cc..ed4926c 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
     LTEXT "Vitesse :", -1, 19, 48, 60, 8
     GROUPBOX "Activité", -1, 9, 74, 182, 70, BS_GROUPBOX
     RTEXT "Envoyés", -1, 26, 90, 60, 8
-    ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+    ICON "", IDC_NETSTAT, 110, 85, 32, 32
     LTEXT "Reçus", -1, 149, 90, 37, 8
     LTEXT "Octets :", -1, 17, 115, 32, 8
     RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index dc6b750..1365ac4 100644 (file)
@@ -36,7 +36,7 @@ BEGIN
  LTEXT "Sebesség:", -1, 19, 48, 60, 8
  GROUPBOX "Tevékenység", -1, 9, 74, 182, 70, BS_GROUPBOX
  RTEXT "Elküldött", -1, 26, 90, 60, 8
- ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+ ICON "", IDC_NETSTAT, 110, 85, 32, 32
  LTEXT "Beérkezett", -1, 149, 90, 37, 8
  LTEXT "Bytes:", -1, 17, 115, 32, 8
  RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index b693619..25675a7 100644 (file)
@@ -36,7 +36,7 @@ BEGIN
  LTEXT "Kecepatan:", -1, 19, 48, 60, 8
  GROUPBOX "Aktivitas", -1, 9, 74, 182, 70, BS_GROUPBOX
  RTEXT "Dikirim", -1, 26, 90, 60, 8
- ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+ ICON "", IDC_NETSTAT, 110, 85, 32, 32
  LTEXT "Diterima", -1, 149, 90, 37, 8
  LTEXT "Bytes:", -1, 17, 115, 32, 8
  RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index b7168ea..5084bd7 100644 (file)
@@ -39,7 +39,7 @@ BEGIN
  GROUPBOX "Attività", -1, 9, 74, 182, 70, BS_GROUPBOX
  RTEXT "Inviati", -1, 26, 90, 60, 8
  ICON IDI_HORIZONTAL, -1, 90, 85, 18, 20
- ICON IDI_NETSTAT, -1, 110, 85, 18, 20
+ ICON "", IDC_NETSTAT, 110, 85, 18, 20
  ICON IDI_HORIZONTAL, -1, 130, 85, 18, 20
  LTEXT "Ricevuti", -1, 149, 90, 37, 8
  LTEXT "Byte:", -1, 17, 115, 32, 8
index c9bdf75..dfe0ff7 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
     LTEXT "\91¬\93x:", -1, 19, 48, 60, 8
     GROUPBOX "\93®\8dì\8fó\8bµ", -1, 9, 74, 182, 70, BS_GROUPBOX
     RTEXT "\91\97\90M", -1, 26, 90, 60, 8
-    ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+    ICON "", IDC_NETSTAT, 110, 85, 32, 32
     LTEXT "\8eó\90M", -1, 149, 90, 37, 8
     LTEXT "\83o\83C\83g:", -1, 17, 115, 32, 8
     RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index 914abce..bae6286 100644 (file)
@@ -39,7 +39,7 @@ BEGIN
     LTEXT "Snelheid:", -1, 19, 48, 60, 8
     GROUPBOX "Activiteit", -1, 9, 74, 182, 70, BS_GROUPBOX
     RTEXT "Verzonden", -1, 26, 90, 60, 8
-    ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+    ICON "", IDC_NETSTAT, 110, 85, 32, 32
     LTEXT "Ontvangen", -1, 149, 90, 37, 8
     LTEXT "Bytes:", -1, 17, 115, 32, 8
     RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index 31fafa2..b93f142 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
     LTEXT "Hastighet:", -1, 19, 48, 60, 8
     GROUPBOX "Aktivitet", -1, 9, 74, 182, 70, BS_GROUPBOX
     RTEXT "Sendt", -1, 26, 90, 60, 8
-    ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+    ICON "", IDC_NETSTAT, 110, 85, 32, 32
     LTEXT "Mottatt", -1, 149, 90, 37, 8
     LTEXT "Byte:", -1, 17, 115, 32, 8
     RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index f8c9cc8..38ff75b 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
  LTEXT "Szybko\9cæ:", -1, 19, 48, 60, 8
  GROUPBOX "Aktywno\9cæ", -1, 9, 74, 182, 70, BS_GROUPBOX
  RTEXT "Wys³ano", -1, 26, 90, 60, 8
- ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+ ICON "", IDC_NETSTAT, 110, 85, 32, 32
  LTEXT "Odebrano", -1, 149, 90, 37, 8
  LTEXT "bajtów:", -1, 17, 115, 32, 8
  RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index 3a52b7d..06ca39c 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
     LTEXT "Vitezã:", -1, 19, 48, 60, 8
     GROUPBOX "Activitate", -1, 9, 74, 182, 70, BS_GROUPBOX
     RTEXT "Trimis", -1, 26, 90, 60, 8
-    ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+    ICON "", IDC_NETSTAT, 110, 85, 32, 32
     LTEXT "Primit", -1, 149, 90, 37, 8
     LTEXT "Octeþi:", -1, 17, 115, 32, 8
     RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index 74c2b69..91daab6 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
        LTEXT "Ñêîðîñòü:", -1, 19, 48, 60, 8
        GROUPBOX "Àêòèâíîñòü", -1, 9, 74, 198, 70, BS_GROUPBOX
        RTEXT "Îòïðàâëåíî", -1, 20, 90, 60, 8
-        ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+        ICON "", IDC_NETSTAT, 110, 85, 32, 32
        LTEXT "Ïðèíÿòî", -1, 158, 90, 37, 8
        LTEXT "Áàéò:", -1, 17, 115, 32, 8
        RTEXT "000.000.000", IDC_SEND, 54, 115, 44, 8
index d7243c4..78651fc 100644 (file)
@@ -37,7 +37,7 @@ BEGIN
  LTEXT "Hastighet:", -1, 19, 48, 60, 8
  GROUPBOX "Aktivitet", -1, 9, 74, 182, 70, BS_GROUPBOX
  RTEXT "Skickat", -1, 26, 90, 60, 8
- ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+ ICON "", IDC_NETSTAT, 110, 85, 32, 32
  LTEXT "Mottaget", -1, 149, 90, 37, 8
  LTEXT "Bytes:", -1, 17, 115, 32, 8
  RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index a8abd40..f109166 100644 (file)
@@ -45,7 +45,7 @@ BEGIN
  LTEXT "Øâèäê³ñòü:", -1, 19, 48, 60, 8
  GROUPBOX "Àêòèâí³ñòü", -1, 9, 74, 182, 70, BS_GROUPBOX
  RTEXT "Íàä³ñëàíî", -1, 26, 90, 60, 8
- ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+ ICON "", IDC_NETSTAT, 110, 85, 32, 32
  LTEXT "Îòðèìàíî", -1, 149, 90, 37, 8
  LTEXT "Áàéò³â:", -1, 17, 115, 32, 8
  RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index 184a73c..45acd1f 100644 (file)
@@ -36,7 +36,7 @@ BEGIN
  LTEXT "ËÙ¶È:", -1, 19, 48, 60, 8
  GROUPBOX "Activity", -1, 9, 74, 182, 70, BS_GROUPBOX
  RTEXT "·¢ËÍ", -1, 26, 90, 60, 8
- ICON IDI_NETSTAT, -1, 110, 85, 32, 32
+ ICON "", IDC_NETSTAT, 110, 85, 32, 32
  LTEXT "½ÓÊÕ", -1, 149, 90, 37, 8
  LTEXT "Bytes:", -1, 17, 115, 32, 8
  RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
index 3691289..1292ef1 100644 (file)
@@ -165,8 +165,8 @@ UpdateLanStatus(HWND hwndDlg,  LANSTATUSUI_CONTEXT * pContext)
         }
         else if (pContext->dwInOctets != IfEntry.dwInOctets && pContext->dwOutOctets != IfEntry.dwOutOctets && pContext->Status  != 1)
         {
+            hIcon = LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_TRANSREC), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
             pContext->Status = 1;
-            hIcon = LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_TRANSREC), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
         }
         else if (pContext->dwInOctets != IfEntry.dwInOctets && pContext->Status  != 2)
         {
@@ -196,7 +196,7 @@ UpdateLanStatus(HWND hwndDlg,  LANSTATUSUI_CONTEXT * pContext)
         }
     }
 
-    if (hwndDlg)
+    if (hwndDlg && hIcon)
     {
         hOldIcon = (HICON)SendDlgItemMessageW(hwndDlg, IDC_NETSTAT, STM_SETICON, (WPARAM)hIcon, 0);
         if (hOldIcon)
index e077b05..f6e77d4 100644 (file)
@@ -1236,7 +1236,7 @@ AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries,
     DWORD ObjectsPresent;
     BOOL needToClean;
     PSID pSid1, pSid2;
-    ULONG i;
+    ULONG i, j;
     LSA_HANDLE PolicyHandle = NULL;
     BOOL bRet;
     DWORD LastErr;
@@ -1295,11 +1295,11 @@ AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries,
             case REVOKE_ACCESS:
             case SET_ACCESS:
                 /* Discard all accesses for the trustee... */
-                for (i = 0; i < SizeInformation.AceCount; i++)
+                for (j = 0; j < SizeInformation.AceCount; j++)
                 {
-                    if (!pKeepAce[i])
+                    if (!pKeepAce[j])
                         continue;
-                    if (!GetAce(OldAcl, i, (PVOID*)&pAce))
+                    if (!GetAce(OldAcl, j, (PVOID*)&pAce))
                     {
                         Ret = GetLastError();
                         goto Cleanup;
@@ -1308,7 +1308,7 @@ AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries,
                     pSid2 = AccpGetAceSid(pAce);
                     if (RtlEqualSid(pSid1, pSid2))
                     {
-                        pKeepAce[i] = FALSE;
+                        pKeepAce[j] = FALSE;
                         SizeInformation.AclBytesInUse -= pAce->AceSize;
                     }
                 }
index 12f8314..0fb074d 100644 (file)
@@ -1506,7 +1506,7 @@ HRESULT WINAPI CoCreateGuid(GUID *pguid)
  * SEE ALSO
  *  StringFromCLSID
  */
-static HRESULT __CLSIDFromString(LPCWSTR s, CLSID *id)
+static HRESULT __CLSIDFromString(LPCWSTR s, LPCLSID id)
 {
   int  i;
   BYTE table[256];
@@ -1566,7 +1566,7 @@ static HRESULT __CLSIDFromString(LPCWSTR s, CLSID *id)
 
 /*****************************************************************************/
 
-HRESULT WINAPI CLSIDFromString(LPOLESTR idstr, CLSID *id )
+HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id )
 {
     HRESULT ret;
 
@@ -4153,11 +4153,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
     case DLL_PROCESS_ATTACH:
         hProxyDll = hinstDLL;
         COMPOBJ_InitProcess();
-       if (TRACE_ON(ole)) CoRegisterMallocSpy((LPVOID)-1);
        break;
 
     case DLL_PROCESS_DETACH:
-        if (TRACE_ON(ole)) CoRevokeMallocSpy();
         OLEDD_UnInitialize();
         COMPOBJ_UninitProcess();
         RPC_UnregisterAllChannelHooks();
index 1380285..d8f4bf6 100644 (file)
@@ -204,8 +204,11 @@ FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, vo
         hres = IStream_Write (pStm, &object, sizeof (object), NULL);
         if (hres != S_OK) return STG_E_MEDIUMFULL;
 
-        hres = IStream_Write (pStm, &constant, sizeof (constant), NULL);
-        if (hres != S_OK) return STG_E_MEDIUMFULL;
+        if (sizeof(object) == sizeof(DWORD))
+        {
+            hres = IStream_Write (pStm, &constant, sizeof (constant), NULL);
+            if (hres != S_OK) return STG_E_MEDIUMFULL;
+        }
 
         hres = IStream_Write (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
         if (hres != S_OK) return STG_E_MEDIUMFULL;
@@ -237,10 +240,13 @@ FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid,
     hres = IStream_Read (pStm, &object, sizeof (object), NULL);
     if (hres != S_OK) return STG_E_READFAULT;
 
-    hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
-    if (hres != S_OK) return STG_E_READFAULT;
-    if (constant != 0)
-        FIXME("constant is 0x%x instead of 0\n", constant);
+    if (sizeof(object) == sizeof(DWORD))
+    {
+        hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
+        if (hres != S_OK) return STG_E_READFAULT;
+        if (constant != 0)
+            FIXME("constant is 0x%x instead of 0\n", constant);
+    }
 
     hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
     if (hres != S_OK) return STG_E_READFAULT;
@@ -267,10 +273,13 @@ static HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream
     hres = IStream_Read (pStm, &object, sizeof (object), NULL);
     if (hres != S_OK) return STG_E_READFAULT;
 
-    hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
-    if (hres != S_OK) return STG_E_READFAULT;
-    if (constant != 0)
-        FIXME("constant is 0x%x instead of 0\n", constant);
+    if (sizeof(object) == sizeof(DWORD))
+    {
+        hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
+        if (hres != S_OK) return STG_E_READFAULT;
+        if (constant != 0)
+            FIXME("constant is 0x%x instead of 0\n", constant);
+    }
 
     hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
     if (hres != S_OK) return STG_E_READFAULT;
index dc625bc..c6a6962 100644 (file)
@@ -359,173 +359,6 @@ static const IMallocVtbl VT_IMalloc32 =
        IMalloc_fnHeapMinimize
 };
 
-/******************************************************************************
- *     IMallocSpy implementation
- *****************************************************************************/
-
-/* set the vtable later */
-static const IMallocSpyVtbl VT_IMallocSpy;
-
-typedef struct {
-        const IMallocSpyVtbl *lpVtbl;
-        LONG ref;
-} _MallocSpy;
-
-/* this is the static object instance */
-static _MallocSpy MallocSpy = {&VT_IMallocSpy, 0};
-
-/******************************************************************************
- *     IMalloc32_QueryInterface        [VTABLE]
- */
-static HRESULT WINAPI IMallocSpy_fnQueryInterface(LPMALLOCSPY iface,REFIID refiid,LPVOID *obj)
-{
-
-       TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
-
-       if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMallocSpy,refiid)) {
-               *obj = &MallocSpy;
-               return S_OK;
-       }
-       return E_NOINTERFACE;
-}
-
-/******************************************************************************
- *     IMalloc32_AddRef                [VTABLE]
- */
-static ULONG WINAPI IMallocSpy_fnAddRef (LPMALLOCSPY iface)
-{
-
-    _MallocSpy *This = (_MallocSpy *)iface;
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE ("(%p)->(count=%u)\n", This, ref - 1);
-
-    return ref;
-}
-
-/******************************************************************************
- *     IMalloc32_AddRelease            [VTABLE]
- *
- * NOTES
- *   Our MallocSpy is static. If the count reaches 0 we dump the leaks
- */
-static ULONG WINAPI IMallocSpy_fnRelease (LPMALLOCSPY iface)
-{
-
-    _MallocSpy *This = (_MallocSpy *)iface;
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE ("(%p)->(count=%u)\n", This, ref + 1);
-
-    if (!ref) {
-        /* our allocation list MUST be empty here */
-    }
-    return ref;
-}
-
-static ULONG WINAPI IMallocSpy_fnPreAlloc(LPMALLOCSPY iface, ULONG cbRequest)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->(%u)\n", This, cbRequest);
-    return cbRequest;
-}
-static PVOID WINAPI IMallocSpy_fnPostAlloc(LPMALLOCSPY iface, void* pActual)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->(%p)\n", This, pActual);
-    return pActual;
-}
-
-static PVOID WINAPI IMallocSpy_fnPreFree(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
-    return pRequest;
-}
-static void  WINAPI IMallocSpy_fnPostFree(LPMALLOCSPY iface, BOOL fSpyed)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->(%u)\n", This, fSpyed);
-}
-
-static ULONG WINAPI IMallocSpy_fnPreRealloc(LPMALLOCSPY iface, void* pRequest, ULONG cbRequest, void** ppNewRequest, BOOL fSpyed)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->(%p %u %u)\n", This, pRequest, cbRequest, fSpyed);
-    *ppNewRequest = pRequest;
-    return cbRequest;
-}
-
-static PVOID WINAPI IMallocSpy_fnPostRealloc(LPMALLOCSPY iface, void* pActual, BOOL fSpyed)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->(%p %u)\n", This, pActual, fSpyed);
-    return pActual;
-}
-
-static PVOID WINAPI IMallocSpy_fnPreGetSize(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->(%p %u)\n", This,  pRequest, fSpyed);
-    return pRequest;
-}
-
-static ULONG WINAPI IMallocSpy_fnPostGetSize(LPMALLOCSPY iface, ULONG cbActual, BOOL fSpyed)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->(%u %u)\n", This, cbActual, fSpyed);
-    return cbActual;
-}
-
-static PVOID WINAPI IMallocSpy_fnPreDidAlloc(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
-    return pRequest;
-}
-
-static int WINAPI IMallocSpy_fnPostDidAlloc(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed, int fActual)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->(%p %u %u)\n", This, pRequest, fSpyed, fActual);
-    return fActual;
-}
-
-static void WINAPI IMallocSpy_fnPreHeapMinimize(LPMALLOCSPY iface)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->()\n", This);
-}
-
-static void WINAPI IMallocSpy_fnPostHeapMinimize(LPMALLOCSPY iface)
-{
-    _MallocSpy *This = (_MallocSpy *)iface;
-    TRACE ("(%p)->()\n", This);
-}
-
-static void MallocSpyDumpLeaks(void) {
-        TRACE("leaks: %u\n", Malloc32.SpyedAllocationsLeft);
-}
-
-static const IMallocSpyVtbl VT_IMallocSpy =
-{
-       IMallocSpy_fnQueryInterface,
-       IMallocSpy_fnAddRef,
-       IMallocSpy_fnRelease,
-       IMallocSpy_fnPreAlloc,
-       IMallocSpy_fnPostAlloc,
-       IMallocSpy_fnPreFree,
-       IMallocSpy_fnPostFree,
-       IMallocSpy_fnPreRealloc,
-       IMallocSpy_fnPostRealloc,
-       IMallocSpy_fnPreGetSize,
-       IMallocSpy_fnPostGetSize,
-       IMallocSpy_fnPreDidAlloc,
-       IMallocSpy_fnPostDidAlloc,
-       IMallocSpy_fnPreHeapMinimize,
-       IMallocSpy_fnPostHeapMinimize
-};
-
 /******************************************************************************
  *             CoGetMalloc     [OLE32.@]
  *
@@ -620,9 +453,6 @@ HRESULT WINAPI CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy)
 
        TRACE("\n");
 
-       /* HACK TO ACTIVATE OUT SPY */
-       if (pMallocSpy == (LPVOID)-1) pMallocSpy =(IMallocSpy*)&MallocSpy;
-
        if(Malloc32.pSpy) return CO_E_OBJISREG;
 
         EnterCriticalSection(&IMalloc32_SpyCS);
@@ -661,11 +491,6 @@ HRESULT WINAPI CoRevokeMallocSpy(void)
 
         EnterCriticalSection(&IMalloc32_SpyCS);
 
-       /* if it's our spy it's time to dump the leaks */
-       if (Malloc32.pSpy == (IMallocSpy*)&MallocSpy) {
-           MallocSpyDumpLeaks();
-       }
-
        if (Malloc32.SpyedAllocationsLeft) {
             TRACE("SpyReleasePending with %u allocations left\n", Malloc32.SpyedAllocationsLeft);
            Malloc32.SpyReleasePending = TRUE;
index a7c5a11..2fb03ae 100644 (file)
@@ -127,6 +127,7 @@ static BOOL start_rpcss(void)
     WCHAR cmd[MAX_PATH];
     static const WCHAR rpcss[] = {'\\','r','p','c','s','s','.','e','x','e',0};
     BOOL rslt;
+    void *redir;
 
     TRACE("\n");
 
@@ -135,7 +136,9 @@ static BOOL start_rpcss(void)
     GetSystemDirectoryW( cmd, MAX_PATH - sizeof(rpcss)/sizeof(WCHAR) );
     strcatW( cmd, rpcss );
 
+    Wow64DisableWow64FsRedirection( &redir );
     rslt = CreateProcessW( cmd, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
+    Wow64RevertWow64FsRedirection( redir );
 
     if (rslt)
     {
index 24f60c8..85710a6 100644 (file)
@@ -20,6 +20,7 @@
        <library>ole32_irot_client</library>
        <library>ole32_proxy</library>
        <library>rpcrt4</library>
+       <library>kernel32</library>
        <library>ntdll</library>
        <library>uuid</library>
        <library>pseh</library>
index 0daa4ab..75b6b1f 100644 (file)
@@ -144,6 +144,28 @@ typedef struct
     /* [size_is((size+7)&~7)] */ unsigned char data[1];
 } WIRE_ORPC_EXTENT;
 
+typedef struct
+{
+    ULONG size;
+    ULONG reserved;
+    unsigned char extent[1];
+} WIRE_ORPC_EXTENT_ARRAY;
+
+typedef struct
+{
+    ULONG version;
+    ULONG flags;
+    ULONG reserved1;
+    GUID  cid;
+    unsigned char extensions[1];
+} WIRE_ORPCTHIS;
+
+typedef struct
+{
+    ULONG flags;
+    unsigned char extensions[1];
+} WIRE_ORPCTHAT;
+
 struct channel_hook_entry
 {
     struct list entry;
@@ -503,10 +525,10 @@ static HRESULT WINAPI ServerRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
     extensions_size = ChannelHooks_ServerGetSize(&message_state->channel_hook_info,
                                                  &channel_hook_data, &channel_hook_count, &extension_count);
 
-    msg->BufferLength += FIELD_OFFSET(ORPCTHAT, extensions) + 4;
+    msg->BufferLength += FIELD_OFFSET(WIRE_ORPCTHAT, extensions) + sizeof(DWORD);
     if (extensions_size)
     {
-        msg->BufferLength += FIELD_OFFSET(ORPC_EXTENT_ARRAY, extent) + 2*sizeof(DWORD) + extensions_size;
+        msg->BufferLength += FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent[2*sizeof(DWORD) + extensions_size]);
         if (extension_count & 1)
             msg->BufferLength += FIELD_OFFSET(WIRE_ORPC_EXTENT, data[0]);
     }
@@ -523,7 +545,7 @@ static HRESULT WINAPI ServerRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
         status = I_RpcGetBuffer(msg);
 
     orpcthat = msg->Buffer;
-    msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(ORPCTHAT, extensions);
+    msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPCTHAT, extensions);
 
     orpcthat->flags = ORPCF_NULL /* FIXME? */;
 
@@ -533,10 +555,10 @@ static HRESULT WINAPI ServerRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
 
     if (extensions_size)
     {
-        ORPC_EXTENT_ARRAY *orpc_extent_array = msg->Buffer;
+        WIRE_ORPC_EXTENT_ARRAY *orpc_extent_array = msg->Buffer;
         orpc_extent_array->size = extension_count;
         orpc_extent_array->reserved = 0;
-        msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(ORPC_EXTENT_ARRAY, extent);
+        msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent);
         /* NDR representation of orpc_extent_array->extent */
         *(DWORD *)msg->Buffer = 1;
         msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
@@ -645,10 +667,10 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
     extensions_size = ChannelHooks_ClientGetSize(&message_state->channel_hook_info,
         &channel_hook_data, &channel_hook_count, &extension_count);
 
-    msg->BufferLength += FIELD_OFFSET(ORPCTHIS, extensions) + 4;
+    msg->BufferLength += FIELD_OFFSET(WIRE_ORPCTHIS, extensions) + sizeof(DWORD);
     if (extensions_size)
     {
-        msg->BufferLength += FIELD_OFFSET(ORPC_EXTENT_ARRAY, extent) + 2*sizeof(DWORD) + extensions_size;
+        msg->BufferLength += FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent[2*sizeof(DWORD) + extensions_size]);
         if (extension_count & 1)
             msg->BufferLength += FIELD_OFFSET(WIRE_ORPC_EXTENT, data[0]);
     }
@@ -703,7 +725,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
     if (status == RPC_S_OK)
     {
         orpcthis = msg->Buffer;
-        msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(ORPCTHIS, extensions);
+        msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPCTHIS, extensions);
 
         orpcthis->version.MajorVersion = COM_MAJOR_VERSION;
         orpcthis->version.MinorVersion = COM_MINOR_VERSION;
@@ -720,7 +742,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
             ORPC_EXTENT_ARRAY *orpc_extent_array = msg->Buffer;
             orpc_extent_array->size = extension_count;
             orpc_extent_array->reserved = 0;
-            msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(ORPC_EXTENT_ARRAY, extent);
+            msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent);
             /* NDR representation of orpc_extent_array->extent */
             *(DWORD *)msg->Buffer = 1;
             msg->Buffer = (char *)msg->Buffer + sizeof(DWORD);
@@ -1152,8 +1174,8 @@ static HRESULT unmarshal_ORPC_EXTENT_ARRAY(RPC_MESSAGE *msg, const char *end,
     DWORD pointer_id;
     DWORD i;
 
-    memcpy(extensions, msg->Buffer, FIELD_OFFSET(ORPC_EXTENT_ARRAY, extent));
-    msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(ORPC_EXTENT_ARRAY, extent);
+    memcpy(extensions, msg->Buffer, FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent));
+    msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPC_EXTENT_ARRAY, extent);
 
     if ((const char *)msg->Buffer + 2 * sizeof(DWORD) > end)
         return RPC_E_INVALID_HEADER;
@@ -1205,14 +1227,14 @@ static HRESULT unmarshal_ORPCTHIS(RPC_MESSAGE *msg, ORPCTHIS *orpcthis,
 
     *first_wire_orpc_extent = NULL;
 
-    if (msg->BufferLength < FIELD_OFFSET(ORPCTHIS, extensions) + 4)
+    if (msg->BufferLength < FIELD_OFFSET(WIRE_ORPCTHIS, extensions) + sizeof(DWORD))
     {
         ERR("invalid buffer length\n");
         return RPC_E_INVALID_HEADER;
     }
 
-    memcpy(orpcthis, msg->Buffer, FIELD_OFFSET(ORPCTHIS, extensions));
-    msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(ORPCTHIS, extensions);
+    memcpy(orpcthis, msg->Buffer, FIELD_OFFSET(WIRE_ORPCTHIS, extensions));
+    msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPCTHIS, extensions);
 
     if ((const char *)msg->Buffer + sizeof(DWORD) > end)
         return RPC_E_INVALID_HEADER;
@@ -1256,14 +1278,14 @@ static HRESULT unmarshal_ORPCTHAT(RPC_MESSAGE *msg, ORPCTHAT *orpcthat,
 
     *first_wire_orpc_extent = NULL;
 
-    if (msg->BufferLength < FIELD_OFFSET(ORPCTHAT, extensions) + 4)
+    if (msg->BufferLength < FIELD_OFFSET(WIRE_ORPCTHAT, extensions) + sizeof(DWORD))
     {
         ERR("invalid buffer length\n");
         return RPC_E_INVALID_HEADER;
     }
 
-    memcpy(orpcthat, msg->Buffer, FIELD_OFFSET(ORPCTHAT, extensions));
-    msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(ORPCTHAT, extensions);
+    memcpy(orpcthat, msg->Buffer, FIELD_OFFSET(WIRE_ORPCTHAT, extensions));
+    msg->Buffer = (char *)msg->Buffer + FIELD_OFFSET(WIRE_ORPCTHAT, extensions);
 
     if ((const char *)msg->Buffer + sizeof(DWORD) > end)
         return RPC_E_INVALID_HEADER;
index f1706da..434d8b2 100644 (file)
@@ -2583,6 +2583,7 @@ static HRESULT StorageImpl_Construct(
   DWORD        openFlags,
   BOOL         fileBased,
   BOOL         create,
+  ULONG        sector_size,
   StorageImpl** result)
 {
   StorageImpl* This;
@@ -2634,7 +2635,7 @@ static HRESULT StorageImpl_Construct(
   /*
    * Initialize the big block cache.
    */
-  This->bigBlockSize   = DEF_BIG_BLOCK_SIZE;
+  This->bigBlockSize   = sector_size;
   This->smallBlockSize = DEF_SMALL_BLOCK_SIZE;
   This->bigBlockFile   = BIGBLOCKFILE_Construct(hFile,
                                                 pLkbyt,
@@ -2665,8 +2666,12 @@ static HRESULT StorageImpl_Construct(
     This->bigBlockDepotCount    = 1;
     This->bigBlockDepotStart[0] = 0;
     This->rootStartBlock        = 1;
+    This->smallBlockLimit       = LIMIT_TO_USE_SMALL_BLOCK;
     This->smallBlockDepotStart  = BLOCK_END_OF_CHAIN;
-    This->bigBlockSizeBits      = DEF_BIG_BLOCK_SIZE_BITS;
+    if (sector_size == 4096)
+      This->bigBlockSizeBits      = MAX_BIG_BLOCK_SIZE_BITS;
+    else
+      This->bigBlockSizeBits      = MIN_BIG_BLOCK_SIZE_BITS;
     This->smallBlockSizeBits    = DEF_SMALL_BLOCK_SIZE_BITS;
     This->extBigBlockDepotStart = BLOCK_END_OF_CHAIN;
     This->extBigBlockDepotCount = 0;
@@ -2711,6 +2716,8 @@ static HRESULT StorageImpl_Construct(
    */
   This->prevFreeBlock = 0;
 
+  This->firstFreeSmallBlock = 0;
+
   /*
    * Create the block chain abstractions.
    */
@@ -3348,6 +3355,11 @@ static HRESULT StorageImpl_LoadFileHeader(
       OFFSET_ROOTSTARTBLOCK,
       &This->rootStartBlock);
 
+    StorageUtl_ReadDWord(
+      headerBigBlock,
+      OFFSET_SMALLBLOCKLIMIT,
+      &This->smallBlockLimit);
+
     StorageUtl_ReadDWord(
       headerBigBlock,
       OFFSET_SBDEPOTSTART,
@@ -3382,9 +3394,11 @@ static HRESULT StorageImpl_LoadFileHeader(
      * blocks, just make sure they are what we're expecting.
      */
     if ((This->bigBlockSize != MIN_BIG_BLOCK_SIZE && This->bigBlockSize != MAX_BIG_BLOCK_SIZE) ||
-       This->smallBlockSize != DEF_SMALL_BLOCK_SIZE)
+       This->smallBlockSize != DEF_SMALL_BLOCK_SIZE ||
+       This->smallBlockLimit != LIMIT_TO_USE_SMALL_BLOCK)
     {
-       WARN("Broken OLE storage file\n");
+       FIXME("Broken OLE storage file? bigblock=0x%x, smallblock=0x%x, sblimit=0x%x\n",
+           This->bigBlockSize, This->smallBlockSize, This->smallBlockLimit);
        hr = STG_E_INVALIDHEADER;
     }
     else
@@ -3438,7 +3452,6 @@ static void StorageImpl_SaveFileHeader(
     StorageUtl_WriteWord(headerBigBlock,  0x18, 0x3b);
     StorageUtl_WriteWord(headerBigBlock,  0x1a, 0x3);
     StorageUtl_WriteWord(headerBigBlock,  0x1c, (WORD)-2);
-    StorageUtl_WriteDWord(headerBigBlock, 0x38, (DWORD)0x1000);
   }
 
   /*
@@ -3464,6 +3477,11 @@ static void StorageImpl_SaveFileHeader(
     OFFSET_ROOTSTARTBLOCK,
     This->rootStartBlock);
 
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_SMALLBLOCKLIMIT,
+    This->smallBlockLimit);
+
   StorageUtl_WriteDWord(
     headerBigBlock,
     OFFSET_SBDEPOTSTART,
@@ -4341,13 +4359,14 @@ static HRESULT Storage_Construct(
   DWORD        openFlags,
   BOOL         fileBased,
   BOOL         create,
+  ULONG        sector_size,
   StorageBaseImpl** result)
 {
   StorageImpl *newStorage;
   StorageBaseImpl *newTransactedStorage;
   HRESULT hr;
 
-  hr = StorageImpl_Construct(hFile, pwcsName, pLkbyt, openFlags, fileBased, create, &newStorage);
+  hr = StorageImpl_Construct(hFile, pwcsName, pLkbyt, openFlags, fileBased, create, sector_size, &newStorage);
   if (FAILED(hr)) goto end;
 
   if (openFlags & STGM_TRANSACTED)
@@ -4840,6 +4859,7 @@ static StorageInternalImpl* StorageInternalImpl_Construct(
      * Initialize the virtual function table.
      */
     newStorage->base.lpVtbl = &Storage32InternalImpl_Vtbl;
+    newStorage->base.pssVtbl = &IPropertySetStorage_Vtbl;
     newStorage->base.baseVtbl = &StorageInternalImpl_BaseVtbl;
     newStorage->base.openFlags = (openFlags & ~STGM_CREATE);
 
@@ -5710,7 +5730,7 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock(
   ULARGE_INTEGER offsetOfBlockInDepot;
   DWORD buffer;
   ULONG bytesRead;
-  ULONG blockIndex = 0;
+  ULONG blockIndex = This->parentStorage->firstFreeSmallBlock;
   ULONG nextBlockIndex = BLOCK_END_OF_CHAIN;
   HRESULT res = S_OK;
   ULONG smallBlocksPerBigBlock;
@@ -5819,6 +5839,8 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock(
     }
   }
 
+  This->parentStorage->firstFreeSmallBlock = blockIndex+1;
+
   smallBlocksPerBigBlock =
     This->parentStorage->bigBlockSize / This->parentStorage->smallBlockSize;
 
@@ -6117,6 +6139,7 @@ static BOOL SmallBlockChainStream_Shrink(
                                                        &blockIndex)))
       return FALSE;
     SmallBlockChainStream_FreeBlock(This, extraBlock);
+    This->parentStorage->firstFreeSmallBlock = min(This->parentStorage->firstFreeSmallBlock, extraBlock);
     extraBlock = blockIndex;
   }
 
@@ -6293,30 +6316,13 @@ static ULARGE_INTEGER SmallBlockChainStream_GetSize(SmallBlockChainStream* This)
   return chainEntry.size;
 }
 
-/******************************************************************************
- *    StgCreateDocfile  [OLE32.@]
- * Creates a new compound file storage object
- *
- * PARAMS
- *  pwcsName  [ I] Unicode string with filename (can be relative or NULL)
- *  grfMode   [ I] Access mode for opening the new storage object (see STGM_ constants)
- *  reserved  [ ?] unused?, usually 0
- *  ppstgOpen [IO] A pointer to IStorage pointer to the new onject
- *
- * RETURNS
- *  S_OK if the file was successfully created
- *  some STG_E_ value if error
- * NOTES
- *  if pwcsName is NULL, create file with new unique name
- *  the function can returns
- *  STG_S_CONVERTED if the specified file was successfully converted to storage format
- *  (unrealized now)
- */
-HRESULT WINAPI StgCreateDocfile(
+static HRESULT create_storagefile(
   LPCOLESTR pwcsName,
   DWORD       grfMode,
-  DWORD       reserved,
-  IStorage  **ppstgOpen)
+  DWORD       grfAttrs,
+  STGOPTIONS* pStgOptions,
+  REFIID      riid,
+  void**      ppstgOpen)
 {
   StorageBaseImpl* newStorage = 0;
   HANDLE       hFile      = INVALID_HANDLE_VALUE;
@@ -6327,13 +6333,10 @@ HRESULT WINAPI StgCreateDocfile(
   DWORD          fileAttributes;
   WCHAR          tempFileName[MAX_PATH];
 
-  TRACE("(%s, %x, %d, %p)\n",
-       debugstr_w(pwcsName), grfMode,
-       reserved, ppstgOpen);
-
   if (ppstgOpen == 0)
     return STG_E_INVALIDPOINTER;
-  if (reserved != 0)
+
+  if (pStgOptions->ulSectorSize != MIN_BIG_BLOCK_SIZE && pStgOptions->ulSectorSize != MAX_BIG_BLOCK_SIZE)
     return STG_E_INVALIDPARAMETER;
 
   /* if no share mode given then DENY_NONE is the default */
@@ -6435,6 +6438,7 @@ HRESULT WINAPI StgCreateDocfile(
          grfMode,
          TRUE,
          TRUE,
+         pStgOptions->ulSectorSize,
          &newStorage);
 
   if (FAILED(hr))
@@ -6442,10 +6446,9 @@ HRESULT WINAPI StgCreateDocfile(
     goto end;
   }
 
-  /*
-   * Get an "out" pointer for the caller.
-   */
-  *ppstgOpen = (IStorage*)newStorage;
+  hr = IStorage_QueryInterface((IStorage*)newStorage, riid, ppstgOpen);
+
+  IStorage_Release((IStorage*)newStorage);
 
 end:
   TRACE("<-- %p  r = %08x\n", *ppstgOpen, hr);
@@ -6453,6 +6456,45 @@ end:
   return hr;
 }
 
+/******************************************************************************
+ *    StgCreateDocfile  [OLE32.@]
+ * Creates a new compound file storage object
+ *
+ * PARAMS
+ *  pwcsName  [ I] Unicode string with filename (can be relative or NULL)
+ *  grfMode   [ I] Access mode for opening the new storage object (see STGM_ constants)
+ *  reserved  [ ?] unused?, usually 0
+ *  ppstgOpen [IO] A pointer to IStorage pointer to the new onject
+ *
+ * RETURNS
+ *  S_OK if the file was successfully created
+ *  some STG_E_ value if error
+ * NOTES
+ *  if pwcsName is NULL, create file with new unique name
+ *  the function can returns
+ *  STG_S_CONVERTED if the specified file was successfully converted to storage format
+ *  (unrealized now)
+ */
+HRESULT WINAPI StgCreateDocfile(
+  LPCOLESTR pwcsName,
+  DWORD       grfMode,
+  DWORD       reserved,
+  IStorage  **ppstgOpen)
+{
+  STGOPTIONS stgoptions = {1, 0, 512};
+
+  TRACE("(%s, %x, %d, %p)\n",
+       debugstr_w(pwcsName), grfMode,
+       reserved, ppstgOpen);
+
+  if (ppstgOpen == 0)
+    return STG_E_INVALIDPOINTER;
+  if (reserved != 0)
+    return STG_E_INVALIDPARAMETER;
+
+  return create_storagefile(pwcsName, grfMode, 0, &stgoptions, &IID_IStorage, (void**)ppstgOpen);
+}
+
 /******************************************************************************
  *              StgCreateStorageEx        [OLE32.@]
  */
@@ -6481,10 +6523,10 @@ HRESULT WINAPI StgCreateStorageEx(const WCHAR* pwcsName, DWORD grfMode, DWORD st
 
     if (stgfmt == STGFMT_STORAGE || stgfmt == STGFMT_DOCFILE)
     {
-        FIXME("Stub: calling StgCreateDocfile, but ignoring pStgOptions and grfAttrs\n");
-        return StgCreateDocfile(pwcsName, grfMode, 0, (IStorage **)ppObjectOpen); 
+        return create_storagefile(pwcsName, grfMode, grfAttrs, pStgOptions, riid, ppObjectOpen);
     }
 
+
     ERR("Invalid stgfmt argument\n");
     return STG_E_INVALIDPARAMETER;
 }
@@ -6707,6 +6749,7 @@ HRESULT WINAPI StgOpenStorage(
          grfMode,
          TRUE,
          FALSE,
+         512,
          &newStorage);
 
   if (FAILED(hr))
@@ -6754,6 +6797,7 @@ HRESULT WINAPI StgCreateDocfileOnILockBytes(
          grfMode,
          FALSE,
          TRUE,
+         512,
          &newStorage);
 
   if (FAILED(hr))
@@ -6801,6 +6845,7 @@ HRESULT WINAPI StgOpenStorageOnILockBytes(
          grfMode,
          FALSE,
          FALSE,
+         512,
          &newStorage);
 
   if (FAILED(hr))
index fad5d77..36a7d67 100644 (file)
@@ -46,6 +46,7 @@ static const ULONG OFFSET_BIGBLOCKSIZEBITS   = 0x0000001e;
 static const ULONG OFFSET_SMALLBLOCKSIZEBITS = 0x00000020;
 static const ULONG OFFSET_BBDEPOTCOUNT      = 0x0000002C;
 static const ULONG OFFSET_ROOTSTARTBLOCK     = 0x00000030;
+static const ULONG OFFSET_SMALLBLOCKLIMIT    = 0x00000038;
 static const ULONG OFFSET_SBDEPOTSTART      = 0x0000003C;
 static const ULONG OFFSET_SBDEPOTCOUNT       = 0x00000040;
 static const ULONG OFFSET_EXTBBDEPOTSTART    = 0x00000044;
@@ -65,6 +66,8 @@ static const ULONG OFFSET_PS_MTIMEHIGH       = 0x00000070;
 static const ULONG OFFSET_PS_STARTBLOCK             = 0x00000074;
 static const ULONG OFFSET_PS_SIZE           = 0x00000078;
 static const WORD  DEF_BIG_BLOCK_SIZE_BITS   = 0x0009;
+static const WORD  MIN_BIG_BLOCK_SIZE_BITS   = 0x0009;
+static const WORD  MAX_BIG_BLOCK_SIZE_BITS   = 0x000c;
 static const WORD  DEF_SMALL_BLOCK_SIZE_BITS = 0x0006;
 static const WORD  DEF_BIG_BLOCK_SIZE        = 0x0200;
 static const WORD  DEF_SMALL_BLOCK_SIZE      = 0x0040;
@@ -97,6 +100,8 @@ static const ULONG DIRENTRY_NULL             = 0xFFFFFFFF;
 #define STGTY_ROOT 0x05
 
 #define COUNT_BBDEPOTINHEADER    109
+
+/* FIXME: This value is stored in the header, but we hard-code it to 0x1000. */
 #define LIMIT_TO_USE_SMALL_BLOCK 0x1000
 
 #define STGM_ACCESS_MODE(stgm)   ((stgm)&0x0000f)
@@ -351,6 +356,7 @@ struct StorageImpl
   ULONG smallBlockSize;
   ULONG bigBlockDepotCount;
   ULONG rootStartBlock;
+  ULONG smallBlockLimit;
   ULONG smallBlockDepotStart;
   ULONG extBigBlockDepotStart;
   ULONG extBigBlockDepotCount;
@@ -360,6 +366,9 @@ struct StorageImpl
   ULONG indexBlockDepotCached;
   ULONG prevFreeBlock;
 
+  /* All small blocks before this one are known to be in use. */
+  ULONG firstFreeSmallBlock;
+
   /*
    * Abstraction of the big block chains for the chains of the header.
    */
index 7a5bc29..c7a3411 100644 (file)
@@ -1273,7 +1273,7 @@ static HRESULT OLEPictureImpl_LoadEnhMetafile(OLEPictureImpl *This,
 static HRESULT OLEPictureImpl_LoadAPM(OLEPictureImpl *This,
                                       const BYTE *data, ULONG size)
 {
-    APM_HEADER *header = (APM_HEADER *)data;
+    const APM_HEADER *header = (const APM_HEADER *)data;
     HMETAFILE hmf;
 
     if (size < sizeof(APM_HEADER))
index 12f64fa..f97544f 100644 (file)
@@ -480,6 +480,12 @@ static struct regsvr_coclass const coclass_list[] = {
        "Obsolete Font",
        "OldFont"
     },
+    {   &IID_ISupportErrorInfo,
+       "PSSupportErrorInfo",
+       "ole2disp.dll",
+       "oleaut32.dll",
+       NULL
+    },
     { NULL }                   /* list terminator */
 };
 
index b09f7ab..5792cc5 100644 (file)
@@ -283,30 +283,9 @@ static WCHAR *get_lcid_subkey( LCID lcid, SYSKIND syskind, WCHAR *buffer )
 static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib);
 
 
-/****************************************************************************
- *             QueryPathOfRegTypeLib   [OLEAUT32.164]
- *
- * Gets the path to a registered type library.
- *
- * PARAMS
- *  guid [I] referenced guid
- *  wMaj [I] major version
- *  wMin [I] minor version
- *  lcid [I] locale id
- *  path [O] path of typelib
- *
- * RETURNS
- *  Success: S_OK.
- *  Failure: If the type library is not registered then TYPE_E_LIBNOTREGISTERED
- *  or TYPE_E_REGISTRYACCESS if the type library registration key couldn't be
- *  opened.
- */
-HRESULT WINAPI QueryPathOfRegTypeLib(
-       REFGUID guid,
-       WORD wMaj,
-       WORD wMin,
-       LCID lcid,
-       LPBSTR path )
+/* Get the path to a registered type library. Helper for QueryPathOfRegTypeLib. */
+static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin,
+                                   SYSKIND syskind, LCID lcid, LPBSTR path )
 {
     HRESULT hr = TYPE_E_LIBNOTREGISTERED;
     LCID myLCID = lcid;
@@ -336,7 +315,7 @@ HRESULT WINAPI QueryPathOfRegTypeLib(
     {
         LONG dwPathLen = sizeof(Path);
 
-        get_lcid_subkey( myLCID, SYS_WIN32, buffer );
+        get_lcid_subkey( myLCID, syskind, buffer );
 
         if (RegQueryValueW(hkey, buffer, Path, &dwPathLen))
         {
@@ -368,6 +347,29 @@ HRESULT WINAPI QueryPathOfRegTypeLib(
     return hr;
 }
 
+/****************************************************************************
+ *             QueryPathOfRegTypeLib   [OLEAUT32.164]
+ *
+ * Gets the path to a registered type library.
+ *
+ * PARAMS
+ *  guid [I] referenced guid
+ *  wMaj [I] major version
+ *  wMin [I] minor version
+ *  lcid [I] locale id
+ *  path [O] path of typelib
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: If the type library is not registered then TYPE_E_LIBNOTREGISTERED
+ *  or TYPE_E_REGISTRYACCESS if the type library registration key couldn't be
+ *  opened.
+ */
+HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID lcid, LPBSTR path )
+{
+    return query_typelib_path( guid, wMaj, wMin, SYS_WIN32, lcid, path );
+}
+
 /******************************************************************************
  * CreateTypeLib [OLEAUT32.160]  creates a typelib
  *
@@ -691,7 +693,10 @@ HRESULT WINAPI RegisterTypeLib(
                        MESSAGE("\n");
                    }
 
-                   if (tattr->wTypeFlags & (TYPEFLAG_FOLEAUTOMATION|TYPEFLAG_FDUAL|TYPEFLAG_FDISPATCHABLE))
+                    /* Register all dispinterfaces (which includes dual interfaces) and
+                       oleautomation interfaces */
+                   if ((kind == TKIND_INTERFACE && (tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
+                        kind == TKIND_DISPATCH)
                    {
                        /* register interface<->typelib coupling */
                        get_interface_key( &tattr->guid, keyName );
@@ -796,7 +801,7 @@ HRESULT WINAPI UnRegisterTypeLib(
     }
 
     /* get the path to the typelib on disk */
-    if (QueryPathOfRegTypeLib(libid, wVerMajor, wVerMinor, lcid, &tlibPath) != S_OK) {
+    if (query_typelib_path(libid, wVerMajor, wVerMinor, syskind, lcid, &tlibPath) != S_OK) {
         result = E_INVALIDARG;
         goto end;
     }
@@ -832,19 +837,23 @@ HRESULT WINAPI UnRegisterTypeLib(
             goto enddeleteloop;
         }
 
-        /* the path to the type */
-        get_interface_key( &typeAttr->guid, subKeyName );
+        if ((kind == TKIND_INTERFACE && (typeAttr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
+            kind == TKIND_DISPATCH)
+        {
+            /* the path to the type */
+            get_interface_key( &typeAttr->guid, subKeyName );
+
+            /* Delete its bits */
+            if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE, &subKey) != ERROR_SUCCESS)
+                goto enddeleteloop;
 
-        /* Delete its bits */
-        if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE, &subKey) != ERROR_SUCCESS) {
-            goto enddeleteloop;
+            RegDeleteKeyW(subKey, ProxyStubClsidW);
+            RegDeleteKeyW(subKey, ProxyStubClsid32W);
+            RegDeleteKeyW(subKey, TypeLibW);
+            RegCloseKey(subKey);
+            subKey = NULL;
+            RegDeleteKeyW(HKEY_CLASSES_ROOT, subKeyName);
         }
-        RegDeleteKeyW(subKey, ProxyStubClsidW);
-        RegDeleteKeyW(subKey, ProxyStubClsid32W);
-        RegDeleteKeyW(subKey, TypeLibW);
-        RegCloseKey(subKey);
-        subKey = NULL;
-        RegDeleteKeyW(HKEY_CLASSES_ROOT, subKeyName);
 
 enddeleteloop:
         if (typeAttr) ITypeInfo_ReleaseTypeAttr(typeInfo, typeAttr);
@@ -1901,7 +1910,7 @@ MSFT_DoFuncs(TLBContext*     pcx,
                     {
                        if (!IS_INTRESOURCE(pFuncRec->OptAttr[2]))
                            ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->OptAttr[2]);
-                       (*pptfd)->Entry = (BSTR)pFuncRec->OptAttr[2];
+                       (*pptfd)->Entry = (BSTR)(DWORD_PTR)LOWORD(pFuncRec->OptAttr[2]);
                     }
                     else
                     {
@@ -2927,7 +2936,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
            else if(td[0] == VT_CARRAY)
             {
                /* array descr table here */
-               pTypeLibImpl->pTypeDesc[i].u.lpadesc = (void *)((int) td[2]);  /* temp store offset in*/
+               pTypeLibImpl->pTypeDesc[i].u.lpadesc = (void *)(INT_PTR)td[2];  /* temp store offset in*/
             }
             else if(td[0] == VT_USERDEFINED)
            {
@@ -2942,7 +2951,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
             if(pTypeLibImpl->pTypeDesc[i].vt != VT_CARRAY) continue;
             if(tlbSegDir.pArrayDescriptions.offset>0)
            {
-                MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) pTypeLibImpl->pTypeDesc[i].u.lpadesc);
+                MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (INT_PTR)pTypeLibImpl->pTypeDesc[i].u.lpadesc);
                 pTypeLibImpl->pTypeDesc[i].u.lpadesc = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
 
                 if(td[1]<0)
@@ -4779,13 +4788,7 @@ static HRESULT WINAPI ITypeLibComp_fnBind(
                 &subtypeinfo, &subdesckind, &subbindptr);
             if (SUCCEEDED(hr) && (subdesckind != DESCKIND_NONE))
             {
-                TYPEDESC tdesc_appobject =
-                {
-                    {
-                        (TYPEDESC *)pTypeInfo->hreftype
-                    },
-                    VT_USERDEFINED
-                };
+                TYPEDESC tdesc_appobject;
                 const VARDESC vardesc_appobject =
                 {
                     -2,         /* memid */
@@ -4807,6 +4810,9 @@ static HRESULT WINAPI ITypeLibComp_fnBind(
                     VAR_STATIC  /* varkind */
                 };
 
+                tdesc_appobject.u.hreftype = pTypeInfo->hreftype;
+                tdesc_appobject.vt = VT_USERDEFINED;
+
                 TRACE("found in implicit app object: %s\n", debugstr_w(szName));
 
                 /* cleanup things filled in by Bind call so we can put our
@@ -5696,7 +5702,8 @@ _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) {
     if (TRACE_ON(ole)) {
        int i;
        TRACE("Calling %p(",func);
-       for (i=0;i<nrargs;i++) TRACE("%08x,",args[i]);
+       for (i=0;i<min(nrargs,30);i++) TRACE("%08x,",args[i]);
+       if (nrargs > 30) TRACE("...");
        TRACE(")\n");
     }
 
@@ -6102,10 +6109,11 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                     continue;
                 }
 
+                src_arg = NULL;
+
                 if (cNamedArgs)
                 {
                     USHORT j;
-                    src_arg = NULL;
                     for (j = 0; j < cNamedArgs; j++)
                         if (rgdispidNamedArgs[j] == i || (i == func_desc->cParams-1 && rgdispidNamedArgs[j] == DISPID_PROPERTYPUT))
                         {
@@ -6113,9 +6121,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                             break;
                         }
                 }
-                else
+
+                if (!src_arg && vargs_converted + cNamedArgs < pDispParams->cArgs)
                 {
-                    src_arg = vargs_converted < pDispParams->cArgs ? &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted] : NULL;
+                    src_arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
                     vargs_converted++;
                 }
 
@@ -6596,7 +6605,7 @@ static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid
            if (pBstrName)
                *pBstrName = NULL;
            if (pwOrdinal)
-               *pwOrdinal = (DWORD)pFDesc->Entry;
+               *pwOrdinal = LOWORD(pFDesc->Entry);
            return S_OK;
         }
     return TYPE_E_ELEMENTNOTFOUND;
index 6b1aea0..a93e5a4 100644 (file)
@@ -2456,7 +2456,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
             return hres;
         }
 
-        This->typeinfo->cbSizeVft = typeattr->cbSizeVft;
+        This->typeinfo->cbSizeVft = typeattr->cbSizeVft * 4 / sizeof(void *);
 
         ITypeInfo_ReleaseTypeAttr(inherited, typeattr);
         ITypeInfo_Release(inherited);
@@ -2928,7 +2928,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr(
         (*ppTypeAttr)->cFuncs += 7;
     (*ppTypeAttr)->cVars = This->typeinfo->cElement>>16;
     (*ppTypeAttr)->cImplTypes = This->typeinfo->cImplTypes;
-    (*ppTypeAttr)->cbSizeVft = This->typekind==TKIND_DISPATCH ? 28 : This->typeinfo->cbSizeVft;
+    (*ppTypeAttr)->cbSizeVft = This->typekind==TKIND_DISPATCH ? 7 * sizeof(void*) : This->typeinfo->cbSizeVft;
     (*ppTypeAttr)->cbAlignment = (This->typeinfo->typekind>>11) & 0x1f;
     (*ppTypeAttr)->wTypeFlags = This->typeinfo->flags;
     (*ppTypeAttr)->wMajorVerNum = This->typeinfo->version&0xffff;
index da1288d..cfd5e8f 100644 (file)
@@ -3503,7 +3503,7 @@ HRESULT WINAPI VarCyFromR4(FLOAT fltIn, CY* pCyOut)
  */
 HRESULT WINAPI VarCyFromR8(double dblIn, CY* pCyOut)
 {
-#if defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
   /* This code gives identical results to Win32 on Intel.
    * Here we use fp exceptions to catch overflows when storing the value.
    */
index 74ad392..8a5be99 100644 (file)
@@ -3354,6 +3354,33 @@ BOOL WINAPI RSAENH_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam
             setup_key(pCryptKey);
             return TRUE;
 
+        case KP_SALT:
+            switch (pCryptKey->aiAlgid) {
+                case CALG_RC2:
+                case CALG_RC4:
+                    if (!pbData)
+                    {
+                        SetLastError(ERROR_INVALID_PARAMETER);
+                        return FALSE;
+                    }
+                    /* MSDN: the base provider always sets eleven bytes of
+                     * salt value.
+                     */
+                    memcpy(pCryptKey->abKeyValue + pCryptKey->dwKeyLen,
+                           pbData, 11);
+                    pCryptKey->dwSaltLen = 11;
+                    setup_key(pCryptKey);
+                    /* Strange but true: salt length reset to 0 after setting
+                     * it via KP_SALT.
+                     */
+                    pCryptKey->dwSaltLen = 0;
+                    break;
+                default:
+                    SetLastError(NTE_BAD_KEY);
+                    return FALSE;
+            }
+            return TRUE;
+
         case KP_SALT_EX:
         {
             CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pbData;
@@ -3486,8 +3513,16 @@ BOOL WINAPI RSAENH_CPGetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam
                               pCryptKey->dwBlockLen);
         
         case KP_SALT:
-            return copy_param(pbData, pdwDataLen, 
-                    &pCryptKey->abKeyValue[pCryptKey->dwKeyLen], pCryptKey->dwSaltLen);
+            switch (pCryptKey->aiAlgid) {
+                case CALG_RC2:
+                case CALG_RC4:
+                    return copy_param(pbData, pdwDataLen,
+                            &pCryptKey->abKeyValue[pCryptKey->dwKeyLen],
+                            pCryptKey->dwSaltLen);
+                default:
+                    SetLastError(NTE_BAD_KEY);
+                    return FALSE;
+            }
 
         case KP_PADDING:
             dwValue = PKCS5_PADDING;
index 559323c..ea5bb28 100644 (file)
@@ -273,7 +273,7 @@ static const char sha2_hex_digits[] = "0123456789abcdef";
 
 /*** SHA-256: *********************************************************/
 void SHA256_Init(SHA256_CTX* context) {
-       if (context == (SHA256_CTX*)0) {
+       if (context == NULL) {
                return;
        }
        MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
@@ -465,7 +465,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
        }
 
        /* Sanity check: */
-       assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0);
+       assert(context != NULL && data != NULL);
 
        usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
        if (usedspace > 0) {
@@ -490,7 +490,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
        }
        while (len >= SHA256_BLOCK_LENGTH) {
                /* Process as many complete blocks as we can */
-               SHA256_Transform(context, (sha2_word32*)data);
+               SHA256_Transform(context, (const sha2_word32*)data);
                context->bitcount += SHA256_BLOCK_LENGTH << 3;
                len -= SHA256_BLOCK_LENGTH;
                data += SHA256_BLOCK_LENGTH;
@@ -509,10 +509,10 @@ void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
        unsigned int    usedspace;
 
        /* Sanity check: */
-       assert(context != (SHA256_CTX*)0);
+       assert(context != NULL);
 
        /* If no digest buffer is passed, we don't bother doing this: */
-       if (digest != (sha2_byte*)0) {
+       if (digest != NULL) {
                usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
 #ifndef WORDS_BIGENDIAN
                /* Convert FROM host byte order */
@@ -572,9 +572,9 @@ char *SHA256_End(SHA256_CTX* context, char buffer[]) {
        int             i;
 
        /* Sanity check: */
-       assert(context != (SHA256_CTX*)0);
+       assert(context != NULL);
 
-       if (buffer != (char*)0) {
+       if (buffer != NULL) {
                SHA256_Final(digest, context);
 
                for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
@@ -582,7 +582,7 @@ char *SHA256_End(SHA256_CTX* context, char buffer[]) {
                        *buffer++ = sha2_hex_digits[*d & 0x0f];
                        d++;
                }
-               *buffer = (char)0;
+               *buffer = 0;
        } else {
                MEMSET_BZERO(context, sizeof(context));
        }
@@ -601,7 +601,7 @@ char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_S
 
 /*** SHA-512: *********************************************************/
 void SHA512_Init(SHA512_CTX* context) {
-       if (context == (SHA512_CTX*)0) {
+       if (context == NULL) {
                return;
        }
        MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
@@ -787,7 +787,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
        }
 
        /* Sanity check: */
-       assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
+       assert(context != NULL && data != NULL);
 
        usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
        if (usedspace > 0) {
@@ -812,7 +812,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
        }
        while (len >= SHA512_BLOCK_LENGTH) {
                /* Process as many complete blocks as we can */
-               SHA512_Transform(context, (sha2_word64*)data);
+               SHA512_Transform(context, (const sha2_word64*)data);
                ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
                len -= SHA512_BLOCK_LENGTH;
                data += SHA512_BLOCK_LENGTH;
@@ -871,10 +871,10 @@ void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
        sha2_word64     *d = (sha2_word64*)digest;
 
        /* Sanity check: */
-       assert(context != (SHA512_CTX*)0);
+       assert(context != NULL);
 
        /* If no digest buffer is passed, we don't bother doing this: */
-       if (digest != (sha2_byte*)0) {
+       if (digest != NULL) {
                SHA512_Last(context);
 
                /* Save the hash data for output: */
@@ -901,9 +901,9 @@ char *SHA512_End(SHA512_CTX* context, char buffer[]) {
        int             i;
 
        /* Sanity check: */
-       assert(context != (SHA512_CTX*)0);
+       assert(context != NULL);
 
-       if (buffer != (char*)0) {
+       if (buffer != NULL) {
                SHA512_Final(digest, context);
 
                for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
@@ -911,7 +911,7 @@ char *SHA512_End(SHA512_CTX* context, char buffer[]) {
                        *buffer++ = sha2_hex_digits[*d & 0x0f];
                        d++;
                }
-               *buffer = (char)0;
+               *buffer = 0;
        } else {
                MEMSET_BZERO(context, sizeof(context));
        }
@@ -930,7 +930,7 @@ char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_S
 
 /*** SHA-384: *********************************************************/
 void SHA384_Init(SHA384_CTX* context) {
-       if (context == (SHA384_CTX*)0) {
+       if (context == NULL) {
                return;
        }
        MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
@@ -946,10 +946,10 @@ void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
        sha2_word64     *d = (sha2_word64*)digest;
 
        /* Sanity check: */
-       assert(context != (SHA384_CTX*)0);
+       assert(context != NULL);
 
        /* If no digest buffer is passed, we don't bother doing this: */
-       if (digest != (sha2_byte*)0) {
+       if (digest != NULL) {
                SHA512_Last((SHA512_CTX*)context);
 
                /* Save the hash data for output: */
@@ -976,9 +976,9 @@ char *SHA384_End(SHA384_CTX* context, char buffer[]) {
        int             i;
 
        /* Sanity check: */
-       assert(context != (SHA384_CTX*)0);
+       assert(context != NULL);
 
-       if (buffer != (char*)0) {
+       if (buffer != NULL) {
                SHA384_Final(digest, context);
 
                for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
@@ -986,7 +986,7 @@ char *SHA384_End(SHA384_CTX* context, char buffer[]) {
                        *buffer++ = sha2_hex_digits[*d & 0x0f];
                        d++;
                }
-               *buffer = (char)0;
+               *buffer = 0;
        } else {
                MEMSET_BZERO(context, sizeof(context));
        }
index 23d8599..f43150e 100644 (file)
@@ -109,6 +109,12 @@ static SECPKG_FUNCTION_TABLE secPkgFunctionTable[2] =
     NULL, /* SetExtendedInformation */
     NULL, /* SetContextAttributes */
     NULL, /* SetCredentialsAttributes */
+    NULL, /* ChangeAccountPassword */
+    NULL, /* QueryMetaData */
+    NULL, /* ExchangeMetaData */
+    NULL, /* GetCredUIContext */
+    NULL, /* UpdateCredentials */
+    NULL, /* ValidateTargetInfo */
   }, {
     NULL, /* InitializePackage */
     NULL, /* LsaLogonUser */
@@ -139,6 +145,12 @@ static SECPKG_FUNCTION_TABLE secPkgFunctionTable[2] =
     NULL, /* SetExtendedInformation */
     NULL, /* SetContextAttributes */
     NULL, /* SetCredentialsAttributes */
+    NULL, /* ChangeAccountPassword */
+    NULL, /* QueryMetaData */
+    NULL, /* ExchangeMetaData */
+    NULL, /* GetCredUIContext */
+    NULL, /* UpdateCredentials */
+    NULL, /* ValidateTargetInfo */
   }
 };
 
@@ -150,7 +162,7 @@ NTSTATUS WINAPI SpLsaModeInitialize(ULONG LsaVersion, PULONG PackageVersion,
 {
     TRACE("(%u, %p, %p, %p)\n", LsaVersion, PackageVersion, ppTables, pcTables);
 
-    *PackageVersion = SECPKG_INTERFACE_VERSION_3;
+    *PackageVersion = SECPKG_INTERFACE_VERSION_6;
     *pcTables = 2;
     *ppTables = secPkgFunctionTable;
 
index 1d20709..e7556ce 100644 (file)
@@ -399,7 +399,13 @@ InstallOneInterface(
         HeapFree(GetProcessHeap(), 0, Path);
     }
 
-    return SetupInstallFromInfSectionW(NULL, /* FIXME */ hInf, InterfaceSection, SPINST_REGISTRY, hKey, NULL, 0, NULL, NULL, NULL, NULL);
+    if (RegCreateKeyExW(hKey, L"Device Parameters", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hRefKey, NULL) != ERROR_SUCCESS)
+    {
+        RegCloseKey(hKey);
+        return FALSE;
+    }
+
+    return SetupInstallFromInfSectionW(NULL, /* FIXME */ hInf, InterfaceSection, SPINST_REGISTRY, hRefKey, NULL, 0, NULL, NULL, NULL, NULL);
 }
 
 /***********************************************************************
index 29573ac..c1ee9fd 100644 (file)
@@ -1,23 +1,7 @@
-/* Hey, Emacs, open this file with -*- coding: cp1250 -*-
- *
- * Czech resources for SETUPAPI
- *
- * Copyright 2001 Andreas Mohr
- * Copyright 2004 David Kredba
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+/* FILE:        dll/win32/setupapi/lang/cs-CZ.rc
+ * TRANSLATOR:  Radek Liska aka Black_Fox (radekliska at gmail dot com)
+ * THANKS TO:   David Kredba
+ * UPDATED:     2010-01-07
  */
 
 LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
@@ -39,7 +23,7 @@ END
 
 STRINGTABLE DISCARDABLE
 BEGIN
-       IDS_QUERY_REBOOT_TEXT        "Your computer needs to be rebooted to finish installation. Do you want to proceed?"
-       IDS_QUERY_REBOOT_CAPTION     "Reboot"
-       IDS_INF_FILE                 "Setup Information"
+       IDS_QUERY_REBOOT_TEXT        "Aby mohla být instalace dokonèena, musí být poèítaè restartován. Pokraèovat?"
+       IDS_QUERY_REBOOT_CAPTION     "Restartovat"
+       IDS_INF_FILE                 "Instalaèní informace"
 END
index e5aa28f..fa09de0 100644 (file)
@@ -344,7 +344,7 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR
                             else
                                 pdir[3] = '\0';
                             }
-                        if (ShellExecuteA(NULL, "open", psz, NULL, pdir, SW_SHOWNORMAL) < (HINSTANCE)33)
+                        if (ShellExecuteA(NULL, NULL, psz, NULL, pdir, SW_SHOWNORMAL) < (HINSTANCE)33)
                             {
                             char *pszSysMsg = NULL ;
                             FormatMessageA (
@@ -357,7 +357,7 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR
                                 ) ;
                             sprintf (szMsg, "Error: %s", pszSysMsg) ;
                             LocalFree ((HLOCAL)pszSysMsg) ;
-                            MessageBoxA (hwnd, szMsg, "Nix", MB_OK | MB_ICONEXCLAMATION) ;
+                            MessageBoxA (hwnd, szMsg, NULL, MB_OK | MB_ICONEXCLAMATION) ;
 
                             HeapFree(GetProcessHeap(), 0, psz);
                             HeapFree(GetProcessHeap(), 0, pdir);
@@ -612,9 +612,11 @@ int WINAPI RestartDialogEx(HWND hWndOwner, LPCWSTR lpwstrReason, DWORD uFlags, D
 
 int WINAPI LogoffWindowsDialog(HWND hWndOwner)
 {
-   UNIMPLEMENTED;
-   ExitWindowsEx(EWX_LOGOFF, 0);
-   return 0;
+    if (ConfirmDialog(hWndOwner, IDS_LOGOFF_PROMPT, IDS_LOGOFF_TITLE))
+    {
+        ExitWindowsEx(EWX_LOGOFF, 0);
+    }
+    return 0;
 }
 
 /*************************************************************************
index c862c79..0e8ccbf 100644 (file)
@@ -41,6 +41,13 @@ typedef struct
    WCHAR szFolderPath[MAX_PATH];
 }FOLDER_PROPERTIES_CONTEXT, *PFOLDER_PROPERTIES_CONTEXT;
 
+typedef struct
+{
+    WCHAR FileExtension[30];
+    WCHAR FileDescription[100];
+    WCHAR ClassKey[MAX_PATH];
+}FOLDER_FILE_TYPE_ENTRY, *PFOLDER_FILE_TYPE_ENTRY;
+
 typedef struct
 {
    LPCWSTR szKeyName;
@@ -155,20 +162,49 @@ InitializeFileTypesListCtrlColumns(HWND hDlgCtrl)
     RECT clientRect;
     LVCOLUMNW col;
     WCHAR szName[50];
+    DWORD dwStyle;
+    int columnSize = 140;
+
 
     if (!LoadStringW(shell32_hInstance, IDS_COLUMN_EXTENSION, szName, sizeof(szName) / sizeof(WCHAR)))
-        szName[0] = 0;
+    {
+        /* default to english */
+        wcscpy(szName, L"Extensions");
+    }
+
+    /* make sure its null terminated */
     szName[(sizeof(szName)/sizeof(WCHAR))-1] = 0;
 
     GetClientRect(hDlgCtrl, &clientRect);
     ZeroMemory(&col, sizeof(LV_COLUMN));
-    col.mask      = LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT;
-    col.iSubItem  = 0;
-    col.pszText = szName;
-    col.fmt = LVCFMT_LEFT;
-    col.cx        = (clientRect.right - clientRect.left) - GetSystemMetrics(SM_CXVSCROLL);
+    columnSize = 140; //FIXME
+    col.iSubItem   = 0;
+    col.mask      = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT;
+    col.fmt = LVCFMT_FIXED_WIDTH;
+    col.cx         = columnSize | LVCFMT_LEFT;
+    col.cchTextMax = wcslen(szName);
+    col.pszText    = szName;
     (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM)&col);
+
+    if (!LoadStringW(shell32_hInstance, IDS_FILE_TYPES, szName, sizeof(szName) / sizeof(WCHAR)))
+    {
+        /* default to english */
+        wcscpy(szName, L"FileTypes");
+    }
+
+   col.iSubItem   = 1;
+   col.cx         = clientRect.right - clientRect.left - columnSize;
+   col.cchTextMax = wcslen(szName);
+   col.pszText    = szName;
+   (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM)&col);
+
+   /* set full select style */
+   dwStyle = (DWORD) SendMessage(hDlgCtrl, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
+   dwStyle = dwStyle | LVS_EX_FULLROWSELECT;
+   SendMessage(hDlgCtrl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
+
 }
+
 INT
 FindItem(HWND hDlgCtrl, WCHAR * ItemName)
 {
@@ -181,45 +217,105 @@ FindItem(HWND hDlgCtrl, WCHAR * ItemName)
 }
 
 VOID
-InsertFileType(HWND hDlgCtrl, WCHAR * szName, DWORD Size, INT iItem)
+InsertFileType(HWND hDlgCtrl, WCHAR * szName, PINT iItem, WCHAR * szFile)
 {
-    WCHAR szPath[100];
+    PFOLDER_FILE_TYPE_ENTRY Entry;
     HKEY hKey;
     LVITEMW lvItem;
     DWORD dwSize;
 
-    if (FindItem(hDlgCtrl, szName) != -1)
+    if (szName[0] != L'.')
+    {
+        /* FIXME handle URL protocol handlers */
+        return;
+    }
+    /* allocate file type entry */
+    Entry = (PFOLDER_FILE_TYPE_ENTRY)HeapAlloc(GetProcessHeap(), 0, sizeof(FOLDER_FILE_TYPE_ENTRY));
+
+    if (!Entry)
+        return;
+
+    /* open key */
+    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szName, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
         return;
 
-    wcscpy(szPath, szName);
-    /* get the name */
-    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szPath, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+    /* FIXME check for duplicates */
+
+    /* query for the default key */
+    dwSize = sizeof(Entry->ClassKey);
+    if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)Entry->ClassKey, &dwSize) != ERROR_SUCCESS)
+    {
+         /* no link available */
+         Entry->ClassKey[0] = 0;
+    }
+
+    if (Entry->ClassKey[0])
     {
-        if (RegLoadMUIStringW(hKey, L"FriendlyTypeName", szName, Size, NULL, 0, NULL) != ERROR_SUCCESS)
+        HKEY hTemp;
+        /* try open linked key */
+        if (RegOpenKeyExW(HKEY_CLASSES_ROOT, Entry->ClassKey, 0, KEY_READ, &hTemp) == ERROR_SUCCESS)
         {
-            dwSize = Size;
-            if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)szName, &dwSize) != ERROR_SUCCESS)
-            {
-                wcscpy(szName, szPath);
-            }
+            /* use linked key */
+            RegCloseKey(hKey);
+            hKey = hTemp;
         }
-        RegCloseKey(hKey);
-        szName[(Size/sizeof(WCHAR))-1] = 0;
     }
-    wcscat(szPath, L"\\shell");
 
-    ZeroMemory(&lvItem, sizeof(LVITEMW));
-    lvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
-    lvItem.state = LVIS_SELECTED; 
-    lvItem.pszText = szName;
-    lvItem.iItem = iItem;
+    /* read friendly type name */
+    if (RegLoadMUIStringW(hKey, L"FriendlyTypeName", Entry->FileDescription, sizeof(Entry->FileDescription), NULL, 0, NULL) != ERROR_SUCCESS)
+    {
+        /* read file description */
+        dwSize = sizeof(Entry->FileDescription);
+        Entry->FileDescription[0] = 0;
+
+        /* read default key */
+        RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)Entry->FileDescription, &dwSize);
+    }
+
+    /* close key */
+    RegCloseKey(hKey);
+
+    /* convert extension to upper case */
+    wcscpy(Entry->FileExtension, szName);
+    _wcsupr(Entry->FileExtension);
 
-    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szPath, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+    if (!Entry->FileDescription[0])
     {
-        lvItem.lParam = 0;
-        (void)SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&lvItem);
-        RegCloseKey(hKey);
+        /* construct default 'FileExtensionFile' */
+        wcscpy(Entry->FileDescription, &Entry->FileExtension[1]);
+        wcscat(Entry->FileDescription, L" ");
+        wcscat(Entry->FileDescription, szFile);
     }
+
+    ZeroMemory(&lvItem, sizeof(LVITEMW));
+    lvItem.mask = LVIF_TEXT | LVIF_PARAM;
+    lvItem.iSubItem = 0;
+    lvItem.pszText = &Entry->FileExtension[1];
+    lvItem.iItem = *iItem;
+    lvItem.lParam = (LPARAM)Entry;
+    (void)SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&lvItem);
+
+    ZeroMemory(&lvItem, sizeof(LVITEMW));
+    lvItem.mask = LVIF_TEXT;
+    lvItem.pszText = Entry->FileDescription;
+    lvItem.iItem = *iItem;
+    lvItem.iSubItem = 1;
+
+    (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&lvItem);
+    (*iItem)++;
+}
+
+int
+CALLBACK
+ListViewCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
+{
+    PFOLDER_FILE_TYPE_ENTRY Entry1, Entry2;
+
+    Entry1 = (PFOLDER_FILE_TYPE_ENTRY)lParam1;
+    Entry2 = (PFOLDER_FILE_TYPE_ENTRY)lParam2;
+
+    return wcsicmp(Entry1->FileExtension, Entry2->FileExtension);
 }
 
 BOOL
@@ -228,22 +324,70 @@ InitializeFileTypesListCtrl(HWND hwndDlg)
     HWND hDlgCtrl;
     DWORD dwIndex = 0;
     WCHAR szName[50];
+    WCHAR szFile[100];
     DWORD dwName;
+    LVITEMW lvItem;
     INT iItem = 0;
 
     hDlgCtrl = GetDlgItem(hwndDlg, 14000);
     InitializeFileTypesListCtrlColumns(hDlgCtrl);
 
+    szFile[0] = 0;
+    if (!LoadStringW(shell32_hInstance, IDS_SHV_COLUMN1, szFile, sizeof(szFile) / sizeof(WCHAR)))
+    {
+        /* default to english */
+        wcscpy(szFile, L"File");
+    }
+    szFile[(sizeof(szFile)/sizeof(WCHAR))-1] = 0;
+
     dwName = sizeof(szName) / sizeof(WCHAR);
 
     while(RegEnumKeyExW(HKEY_CLASSES_ROOT, dwIndex++, szName, &dwName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
     {
-        InsertFileType(hDlgCtrl, szName, sizeof(szName), iItem++);
+        InsertFileType(hDlgCtrl, szName, &iItem, szFile);
         dwName = sizeof(szName) / sizeof(WCHAR);
     }
+
+    /* sort list */
+    ListView_SortItems(hDlgCtrl, ListViewCompareProc, NULL);
+
+    /* select first item */
+    ZeroMemory(&lvItem, sizeof(LVITEMW));
+    lvItem.mask = LVIF_STATE;
+    lvItem.stateMask = (UINT)-1;
+    lvItem.state = LVIS_FOCUSED|LVIS_SELECTED;
+    lvItem.iItem = 0;
+    (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&lvItem);
+
     return TRUE;
 }
 
+PFOLDER_FILE_TYPE_ENTRY
+FindSelectedItem(
+    HWND hDlgCtrl)
+{
+    UINT Count, Index;
+    LVITEMW lvItem;
+
+    Count = ListView_GetItemCount(hDlgCtrl);
+
+    for (Index = 0; Index < Count; Index++)
+    {
+        ZeroMemory(&lvItem, sizeof(LVITEM));
+        lvItem.mask = LVIF_PARAM | LVIF_STATE;
+        lvItem.iItem = Index;
+        lvItem.stateMask = (UINT)-1;
+
+        if (ListView_GetItem(hDlgCtrl, &lvItem))
+        {
+            if (lvItem.state & LVIS_SELECTED)
+               return (PFOLDER_FILE_TYPE_ENTRY)lvItem.lParam;
+        }
+    }
+
+    return NULL;
+}
+
 
 INT_PTR
 CALLBACK
@@ -251,14 +395,65 @@ FolderOptionsFileTypesDlg(
     HWND hwndDlg,
     UINT uMsg,
     WPARAM wParam,
-    LPARAM lParam
-)
+    LPARAM lParam)
 {
+    LPNMLISTVIEW lppl;
+    LVITEMW lvItem;
+    WCHAR Buffer[200], FormatBuffer[100];
+    PFOLDER_FILE_TYPE_ENTRY pItem;
+    OPENASINFO Info;
+
     switch(uMsg)
     {
         case WM_INITDIALOG:
             InitializeFileTypesListCtrl(hwndDlg);
             return TRUE;
+        case WM_COMMAND:
+            switch(LOWORD(wParam))
+            {
+                case 14006:
+                    pItem = FindSelectedItem(GetDlgItem(hwndDlg, 14000));
+                    if (pItem)
+                    {
+                        Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT;
+                        Info.pcszClass = pItem->FileExtension;
+                        SHOpenWithDialog(hwndDlg, &Info);
+                    }
+                    break;
+            }
+
+            break;
+       case WM_NOTIFY:
+            lppl = (LPNMLISTVIEW) lParam;
+
+            if (lppl->hdr.code == LVN_ITEMCHANGING)
+            {
+                    ZeroMemory(&lvItem, sizeof(LVITEM));
+                    lvItem.mask = LVIF_PARAM;
+                    lvItem.iItem = lppl->iItem;
+                    if (!SendMessageW(lppl->hdr.hwndFrom, LVM_GETITEMW, 0, (LPARAM)&lvItem))
+                        return TRUE;
+
+                    pItem = (PFOLDER_FILE_TYPE_ENTRY)lvItem.lParam;
+                    if (!pItem)
+                        return TRUE;
+
+                    if (!(lppl->uOldState & LVIS_FOCUSED) && (lppl->uNewState & LVIS_FOCUSED))
+                    {
+                        /* new focused item */
+                        if (!LoadStringW(shell32_hInstance, IDS_FILE_DETAILS, FormatBuffer, sizeof(FormatBuffer) / sizeof(WCHAR)))
+                        {
+                            /* use default english format string */
+                            wcscpy(FormatBuffer, L"Details for '%s' extension");
+                        }
+
+                        /* format buffer */
+                        swprintf(Buffer, FormatBuffer, &pItem->FileExtension[1]);
+                        /* update dialog */
+                        SendDlgItemMessageW(hwndDlg, 14003, WM_SETTEXT, 0, (LPARAM)Buffer);
+                    }
+           }
+           break;
     }
 
     return FALSE;
index 9b71506..d1a6c67 100644 (file)
@@ -257,6 +257,7 @@ IExtractIconW* IExtractIconW_Constructor(LPCITEMIDLIST pidl)
                 case DRIVE_CDROM:       icon_idx = IDI_SHELL_CDROM;         break;
                 case DRIVE_REMOTE:      icon_idx = IDI_SHELL_NETDRIVE;      break;
                 case DRIVE_RAMDISK:     icon_idx = IDI_SHELL_RAMDISK;       break;
+                case DRIVE_NO_ROOT_DIR: icon_idx = IDI_SHELL_CDROM;         break;
             }
         }
 
index 529854e..4d9345c 100644 (file)
@@ -114,7 +114,7 @@ SH_FileGeneralSetFileType(HWND hwndDlg, WCHAR *filext)
     {
         /* the file extension is unknown, so default to string "FileExtension File" */
         SendMessageW(hDlgCtrl, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)value);
-        swprintf(name, value, &filext[1]);
+        swprintf(name, L"%s %s", &filext[1], value);
         SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)name);
         return TRUE;
     }
index fea6d98..13a9bdb 100644 (file)
@@ -357,7 +357,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Îòâàðÿíå ñ"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -666,6 +666,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Èñêàòå ëè äà ïðåçàïóñíåòå ñèñòåìàòà?"
        IDS_SHUTDOWN_TITLE          "Èçêëþ÷âàíå"
        IDS_SHUTDOWN_PROMPT         "Èñêàòå ëè äà èçêëþ÷èòå êîìïþòúðà?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        // shell folder path default values 
        IDS_PROGRAMS                "Ïóñêîâ èçáîðíèê\\Ïðèëîæåíèÿ"
@@ -750,6 +752,8 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Ïîäðàçáèðàí ðàçïðåäåëèòåëåí ðàçìåð"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
 
 
index df5cb9e..214028e 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -665,6 +665,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Do you want to restart the system?"
        IDS_SHUTDOWN_TITLE          "Shutdown"
        IDS_SHUTDOWN_PROMPT         "Do you want to shutdown?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -749,4 +751,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index b08beea..1f4fc94 100644 (file)
@@ -1,21 +1,7 @@
-/*
- * Copyright 1998 Juergen Schmied
- * Copyright 2003 Filip Navara
- * Copyright 2008 Radek Liska
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+/* FILE:        dll/win32/shell32/lang/cs-CZ.rc
+ * TRANSLATOR:  Radek Liska aka Black_Fox (radekliska at gmail dot com)
+ * UPDATED:     2010-04-05
+ * THANKS TO:   navaraf, who translated major part of this file
  */
 
 LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
@@ -208,18 +194,18 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
        ICON "", 14000, 10, 3, 30, 30, WS_VISIBLE
        EDITTEXT 14001, 70, 9, 158, 14, ES_LEFT | ES_READONLY
-       LTEXT "Type of file:", 14004, 8, 35, 50, 10
-       LTEXT "Folder", 14005, 68, 35, 160, 10
-       LTEXT "Location:", 14006, 8, 53, 50, 10
+       LTEXT "Typ souboru:", 14004, 8, 35, 50, 10
+       LTEXT "Slo\9eka", 14005, 68, 35, 160, 10
+       LTEXT "Umístìní:", 14006, 8, 53, 50, 10
        LTEXT "", 14007, 68, 53, 315, 10
-       LTEXT "Size:", 14008, 8, 72, 45, 10
+       LTEXT "Velikost:", 14008, 8, 72, 45, 10
        LTEXT "", 14009, 68, 72, 315, 10
-       LTEXT "Contains:", 14010, 8, 93, 45, 10
+       LTEXT "Obsahuje:", 14010, 8, 93, 45, 10
        LTEXT "", 14011, 68, 93, 160, 10
-       LTEXT "Created:", 14014, 8, 118, 45, 10
+       LTEXT "Vytvoøeno:", 14014, 8, 118, 45, 10
        LTEXT "", 14015, 68, 118, 160, 10
-       AUTOCHECKBOX "&Read-only", 14021, 45, 150, 67, 10
-       AUTOCHECKBOX "&Hidden", 14022, 126, 150, 50, 10
+       AUTOCHECKBOX "&Jen pro ètení", 14021, 45, 150, 67, 10
+       AUTOCHECKBOX "&Skrytý", 14022, 126, 150, 50, 10
 END
 
 SHELL_FILE_GENERAL_DLG DIALOGEX 0, 0, 240, 205
@@ -360,7 +346,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Otevøít v..."
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -546,7 +532,7 @@ END
 
 FORMAT_DLG DIALOGEX 50, 50, 184, 218
 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION
-CAPTION "Format"
+CAPTION "Formátování"
 FONT 8, "MS Shell Dlg"
 BEGIN
        DEFPUSHBUTTON "&Spustit", IDOK, 53, 198, 60, 14
@@ -567,14 +553,14 @@ END
 
 CHKDSK_DLG DIALOGEX 50, 50, 194, 120
 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION
-CAPTION "Check Disk"
+CAPTION "Zkontrolovat disk"
 FONT 8, "MS Shell Dlg"
 BEGIN
        DEFPUSHBUTTON "Start", IDOK, 53, 100, 60, 14
-       GROUPBOX "Check disk options", -1, 7, 6, 179, 50
-       PUSHBUTTON "Cancel", IDCANCEL, 118, 100, 60, 14
-       AUTOCHECKBOX "Automatically fix file system errors", 14000, 16, 15, 155, 10
-       AUTOCHECKBOX "&Scan for and attempt recovery of bad sectors", 14001, 16, 30, 165, 10
+       GROUPBOX "Mo\9enosti kontroly disku", -1, 7, 6, 179, 50
+       PUSHBUTTON "Storno", IDCANCEL, 118, 100, 60, 14
+       AUTOCHECKBOX "Automaticky opravovat chyby souborového systému", 14000, 16, 15, 155, 10
+       AUTOCHECKBOX "&Vyhledat a pokusit se obnovit vadné sektory", 14001, 16, 30, 165, 10
        CONTROL "", 14002, "MSCTLS_PROGRESS32", 16, 7, 60, 170, 8
        LTEXT "", 14003, 60, 80, 170, 10
 END
@@ -607,17 +593,17 @@ BEGIN
        IDS_SHV_COLUMN9             "Komentáø"
        IDS_SHV_COLUMN10            "Vlastník"
        IDS_SHV_COLUMN11            "Skupina"
-       IDS_SHV_COLUMN12            "Filename"
-       IDS_SHV_COLUMN13            "Category"
+       IDS_SHV_COLUMN12            "Název souboru"
+       IDS_SHV_COLUMN13            "Kategorie"
        IDS_SHV_COLUMN_DELFROM      "Pùvodní umístìní"
        IDS_SHV_COLUMN_DELDATE      "Odstranìno"
        IDS_SHV_COLUMN_FONTTYPE     "Fonttype"
-       IDS_SHV_COLUMN_WORKGROUP    "Workgroup"
-       IDS_SHV_NETWORKLOCATION     "Network Location"
-       IDS_SHV_COLUMN_DOCUMENTS    "Documents"
+       IDS_SHV_COLUMN_WORKGROUP    "Pracovní skupina"
+       IDS_SHV_NETWORKLOCATION     "\9dové umístìní"
+       IDS_SHV_COLUMN_DOCUMENTS    "Dokumenty"
        IDS_SHV_COLUMN_STATUS       "Status"
-       IDS_SHV_COLUMN_COMMENTS     "Comments"
-       IDS_SHV_COLUMN_LOCATION     "Location"
+       IDS_SHV_COLUMN_COMMENTS     "Komentáøe"
+       IDS_SHV_COLUMN_LOCATION     "Umístìní"
        IDS_SHV_COLUMN_MODEL        "Model"
 
        /* special folders */
@@ -625,7 +611,7 @@ BEGIN
        IDS_MYCOMPUTER              "Tento poèítaè"
        IDS_RECYCLEBIN_FOLDER_NAME  "Ko\9a"
        IDS_CONTROLPANEL            "Ovládací panely"
-       IDS_ADMINISTRATIVETOOLS     "Administrative Tools"
+       IDS_ADMINISTRATIVETOOLS     "Nástroje správy"
 
        /* context menus */
        IDS_VIEW_LARGE              "&Vedle sebe"
@@ -634,15 +620,15 @@ BEGIN
        IDS_VIEW_DETAILS            "&Podrobnosti"
        IDS_SELECT                  "Vybrat"
        IDS_OPEN                    "Otevøít"
-        IDS_CREATELINK              "Vytvoøit zástupc&e"
+       IDS_CREATELINK              "Vytvoøit zástupc&e"
        IDS_COPY                    "&Kopírovat"
        IDS_DELETE                  "O&dstranit"
        IDS_PROPERTIES              "&Vlastnosti"
        IDS_CUT                     "Vyj&mout"
-       IDS_RESTORE                 "Restore"
-       IDS_FORMATDRIVE             "Format..."
-       IDS_RENAME                  "Rename"
-       IDS_INSERT                  "Insert"
+       IDS_RESTORE                 "Obnovit"
+       IDS_FORMATDRIVE             "Formátovat..."
+       IDS_RENAME                  "Pøejmenovat"
+       IDS_INSERT                  "Vlo\9eit"
 
        IDS_CREATEFOLDER_DENIED     "Nelze vytvoøit novou slo\9eku, proto\9ee pøístup byl odepøen."
        IDS_CREATEFOLDER_CAPTION    "Chyba pøi pokusu vytvoøit nový adresáø"
@@ -666,6 +652,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Opravdu chcete restartovat systém?"
        IDS_SHUTDOWN_TITLE          "Vypnout"
        IDS_SHUTDOWN_PROMPT         "Opravdu chcete vypnout poèítaè?"
+       IDS_LOGOFF_TITLE            "Odhlásit se"
+       IDS_LOGOFF_PROMPT           "Opravdu se chcete odhlásit?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Nabídka Start\\Programy"
@@ -735,19 +723,21 @@ BEGIN
        IDS_LNK_FILE                "Zástupce"
        IDS_SYS_FILE                "Systémový soubor"
 
-       IDS_OPEN_VERB               "Open"
-       IDS_RUNAS_VERB              "Run as "
-       IDS_EDIT_VERB               "Edit"
-       IDS_FIND_VERB               "Find"
-       IDS_PRINT_VERB              "Print"
-       IDS_PLAY_VERB               "Play"
-       IDS_PREVIEW_VERB            "Preview"
-
-       IDS_FILE_FOLDER             "%u Files, %u Folders"
-       IDS_PRINTERS                "Printers"
-       IDS_FONTS                   "Fonts"
-       IDS_INSTALLNEWFONT          "Install New Font..."
-
-       IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
-       IDS_COPY_OF                 "Copy of"
+       IDS_OPEN_VERB               "Otevøít"
+       IDS_RUNAS_VERB              "Spustit jako "
+       IDS_EDIT_VERB               "Upravit"
+       IDS_FIND_VERB               "Najít"
+       IDS_PRINT_VERB              "Tisknout"
+       IDS_PLAY_VERB               "Pøehrát"
+       IDS_PREVIEW_VERB            "Náhled"
+
+       IDS_FILE_FOLDER             "%u souborù, %u slo\9eek"
+       IDS_PRINTERS                "Tiskárny"
+       IDS_FONTS                   "Fonty"
+       IDS_INSTALLNEWFONT          "Nainstalovat nový font..."
+
+       IDS_DEFAULT_CLUSTER_SIZE    "Výchozí alokaèní velikost"
+       IDS_COPY_OF                 "Kopie "
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 40e1eab..9ad423c 100644 (file)
@@ -347,7 +347,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -654,6 +654,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Ønsker du at Genstarte Systemet?"
        IDS_SHUTDOWN_TITLE          "Luk Ned"
        IDS_SHUTDOWN_PROMPT         "Ønsker du at Lukke Ned?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programmer"
@@ -738,4 +740,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index db0fa82..5610af6 100644 (file)
@@ -296,7 +296,7 @@ BEGIN
 
        CONTROL "", 14015, "Static", SS_NOTIFY | SS_SUNKEN | SS_OWNERDRAW, 20, 140, 200, 20
 
-       LTEXT "Laufwerk %s", 14009, 100, 170, 40, 10
+       LTEXT "Laufwerk %s", 14009, 100, 170, 50, 10
        PUSHBUTTON "Bereinigen", 14010, 180, 175, 50, 15, WS_TABSTOP
        CHECKBOX "Laufwerk komprimieren, um Speicherplatz zu sparen", 14011, 15, 205, 180, 10, WS_DISABLED
        CHECKBOX "Laufwerk für schnelle Dateisuche indizieren", 14012, 15, 220, 165, 10, WS_DISABLED
@@ -361,17 +361,17 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Öffnen mit"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
        ICON IDI_SHELL_OPEN_WITH, -1, 8, 12, 21, 20
-       LTEXT "Wählen Sie das Programm, das zum Öffnen dieser Datei verwendet werden soll:", -1, 44, 12, 211, 10
-       LTEXT "Datei:    ", 14001, 44, 25, 188, 10
+       LTEXT "Wählen Sie das Programm, das zum Öffnen dieser Datei verwendet werden soll:", -1, 44, 12, 211, 18
+       LTEXT "Datei:    ", 14001, 44, 30, 188, 10
        GROUPBOX "&Programme", -1, 7, 42, 249, 187
         LISTBOX 14002, 16 ,57, 230, 130, LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP, WS_EX_STATICEDGE
        AUTOCHECKBOX "&Dateityp &immer mit dem ausgewählten Programm öffnen", 14003, 20, 193, 225, 10
-       PUSHBUTTON "&Durchsuchen..", 14004, 198, 207, 50, 14
+       PUSHBUTTON "&Durchsuchen...", 14004, 188, 207, 60, 14
        PUSHBUTTON "OK", 14005, 150, 236, 50, 14
        PUSHBUTTON "Abbrechen", 14006, 206, 236, 50, 14
 END
@@ -669,6 +669,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Möchten Sie das System neu starten?"
        IDS_SHUTDOWN_TITLE          "Herunterfahren"
        IDS_SHUTDOWN_PROMPT         "Möchten Sie das System herunterfahren?"
+       IDS_LOGOFF_TITLE            "Ausloggen"
+       IDS_LOGOFF_PROMPT           "Möchten Sie sich ausloggen?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Startmenü\\Programme"
@@ -753,4 +755,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Standardgröße"
        IDS_COPY_OF                 "Kopie von"
+
+    IDS_SHLEXEC_NOASSOC         "Es ist kein Programm mit diesem Dateityp verknüpft."
 END
index 6b35ec3..a269d68 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "¢íïéãìá ìå"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -666,6 +666,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Åßóôå óßãïõñïé üôé èÝëåôå íá åðáíåêêéíÞóåôå ôïí õðïëïãéóôÞ óáò;"
        IDS_SHUTDOWN_TITLE          "Áðåíåñãïðïßçóç"
        IDS_SHUTDOWN_PROMPT         "Åßóôå óßãïõñïé üôé èÝëåôå íá áðåíåñãïðïéÞóåôå ôïí õðïëïãéóôÞ óáò;"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -750,4 +752,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 38203c2..5d8f02c 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -665,6 +665,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Do you want to restart the system?"
        IDS_SHUTDOWN_TITLE          "Shutdown"
        IDS_SHUTDOWN_PROMPT         "Do you want to shutdown?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -749,4 +751,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 63d38cb..04df98d 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -373,6 +373,17 @@ BEGIN
        PUSHBUTTON "Cancel", 14006, 206, 236, 50, 14
 END
 
+IDD_SH_FILE_COPY DIALOGEX 0, 0, 264, 45
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
+CAPTION "Copying..."
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+       PUSHBUTTON "Cancel", 14002, 195, 14, 60, 16 
+       CONTROL "", 14000, "MSCTLS_PROGRESS32", 0, 8, 20, 170, 10
+       LTEXT "File", 14001,  8, 6, 169, 10
+END
+
+
 FOLDER_OPTIONS_GENERAL_DLG DIALOGEX 0, 0, 264, 256
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
 CAPTION "General"
@@ -665,6 +676,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Do you want to restart the system?"
        IDS_SHUTDOWN_TITLE          "Shutdown"
        IDS_SHUTDOWN_PROMPT         "Do you want to shutdown?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -749,4 +762,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 0e20abc..f26e1d4 100644 (file)
@@ -361,7 +361,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 284, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Abrir con"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -668,6 +668,8 @@ BEGIN
        IDS_RESTART_PROMPT          "¿Desea reiniciar el equipo?"
        IDS_SHUTDOWN_TITLE          "Apagar"
        IDS_SHUTDOWN_PROMPT         "¿Desea apagar el equipo?"
+       IDS_LOGOFF_TITLE            "Cerrar sesión"
+       IDS_LOGOFF_PROMPT           "¿Desea cerrar la sesión?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Menú Inicio\\Programas"
@@ -752,4 +754,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Tamaño asignado por defecto"
        IDS_COPY_OF                 "Copia de"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 2620c2b..6469ce1 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -665,6 +665,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Haluatko simuloida Windows:n uudelleenkäynnistämistä?"
        IDS_SHUTDOWN_TITLE          "Sammuta"
        IDS_SHUTDOWN_PROMPT         "Haluatko lopettaa Wine:n istunnon?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Käynnistä\\Ohjelmat"
@@ -749,4 +751,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 98cd95f..3d4932f 100644 (file)
@@ -362,7 +362,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Ouvrir avec"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -669,6 +669,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Voulez-vous redémarrer votre ordinateur ?"
        IDS_SHUTDOWN_TITLE          "Arrêter"
        IDS_SHUTDOWN_PROMPT         "Voulez-vous fermer la session ReactOS ?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Menu Démarrer\\Programmes"
@@ -753,4 +755,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Taille d'allocation par défaut"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "Aucun programme Windows n'est configuré pour ouvrir ce type de fichier."
 END
index 7016d50..e45819a 100644 (file)
@@ -361,7 +361,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -668,6 +668,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Újra szeretnéd indítani a rendszert?"
        IDS_SHUTDOWN_TITLE          "Kikapcsolás"
        IDS_SHUTDOWN_PROMPT         "Kiakarod kapcsolni számítógépét?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -752,4 +754,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 986ecfe..8372b35 100644 (file)
@@ -359,7 +359,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Apri con"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -434,8 +434,8 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUPWIND
 CAPTION "Conferma della sovrascrittura dei file"
 FONT 8, "MS Shell Dlg"
 BEGIN
-       DEFPUSHBUTTON "&Si", IDYES, 20, 122, 60, 14
-       PUSHBUTTON "Si &tutti", 12807, 85, 122, 60, 14
+       DEFPUSHBUTTON "&Sì", IDYES, 20, 122, 60, 14
+       PUSHBUTTON "Sì &tutti", 12807, 85, 122, 60, 14
        PUSHBUTTON "&No", IDNO, 150, 122, 60, 14
        PUSHBUTTON "Annulla", IDCANCEL, 215, 122, 60, 14
        ICON 146, -1, 11, 10, 21, 20, SS_REALSIZECONTROL
@@ -555,13 +555,13 @@ BEGIN
        LTEXT "&File system", -1, 7, 35, 170, 9
        COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP
        CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8
-       LTEXT "Dimensione dell'unità di &Allocazione", -1, 7, 64, 170, 9
+       LTEXT "Dimensione dell'unità di &allocazione", -1, 7, 64, 170, 9
        COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP
        LTEXT "&Etichetta del Volume", -1, 7, 93, 170, 9
        EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL
-       GROUPBOX "Opzioni di &Formattazione", 4610, 7, 121, 170, 49
+       GROUPBOX "Opzioni di &formattazione", 4610, 7, 121, 170, 49
        AUTOCHECKBOX "Formattazione &rapida", 28674, 16, 135, 155, 10
-       AUTOCHECKBOX "Abilita la &Compressione", 28675, 16, 152, 155, 10
+       AUTOCHECKBOX "Abilita la &compressione", 28675, 16, 152, 155, 10
 END
 
 CHKDSK_DLG DIALOGEX 50, 50, 194, 120
@@ -645,7 +645,7 @@ BEGIN
 
        IDS_CREATEFOLDER_DENIED     "Impossibile creare la cartella: Accesso negato."
        IDS_CREATEFOLDER_CAPTION    "Errore durante la creazione della cartella"
-       IDS_DELETEITEM_CAPTION      "Confermare la cancallazione del file"
+       IDS_DELETEITEM_CAPTION      "Confermare la cancellazione del file"
        IDS_DELETEFOLDER_CAPTION    "Confermare la cancellazione della cartella"
        IDS_DELETEITEM_TEXT         "Sei sicuro di voler cancellare '%1'?"
        IDS_DELETEMULTIPLE_TEXT     "Sei sicuro di voler cancellare questi %1 elementi?"
@@ -664,8 +664,10 @@ BEGIN
        /* message box strings */
        IDS_RESTART_TITLE           "Riavvia"
        IDS_RESTART_PROMPT          "Volete riavviare il sistema?"
-       IDS_SHUTDOWN_TITLE          "Termina sessione"
-       IDS_SHUTDOWN_PROMPT         "Volete terminare la sessione di ReactOS?"
+       IDS_SHUTDOWN_TITLE          "Arresta sistema"
+       IDS_SHUTDOWN_PROMPT         "Volete arrestare il sistema?"
+       IDS_LOGOFF_TITLE            "Disconnetti"
+       IDS_LOGOFF_PROMPT           "Volete disconnettervi?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Menu Avvio\\Programmi"
@@ -749,5 +751,7 @@ BEGIN
        IDS_INSTALLNEWFONT          "Installazione nuovi Font..."
 
        IDS_DEFAULT_CLUSTER_SIZE    "Dimensione predefinita di allocazione"
-       IDS_COPY_OF                 "Copy of"
+       IDS_COPY_OF                 "Copia di"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 47c5bfb..c09ba10 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "\8aJ\82­\83v\83\8d\83O\83\89\83\80"
 FONT 9, "MS UI Gothic", 0, 0, 0x0
 BEGIN
@@ -665,6 +665,8 @@ BEGIN
        IDS_RESTART_PROMPT          "\83V\83X\83e\83\80\82ð\8dÄ\8bN\93®\82µ\82Ü\82·\82©?"
        IDS_SHUTDOWN_TITLE          "\83V\83\83\83b\83g\83_\83E\83\93"
        IDS_SHUTDOWN_PROMPT         "\83V\83\83\83b\83g\83_\83E\83\93\82µ\82Ü\82·\82©?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "\83X\83^\81[\83\83\81\83j\83\85\81[\\\83v\83\8d\83O\83\89\83\80"
@@ -749,4 +751,5 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "\83f\83t\83H\83\8b\83\83A\83\8d\83P\81[\83V\83\87\83\93 \83T\83C\83Y"
        IDS_COPY_OF                 "\83R\83s\81\81`"
+    
 END
index e9e67b7..98981f7 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -665,6 +665,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Do you want to restart the system?"
        IDS_SHUTDOWN_TITLE          "Shutdown"
        IDS_SHUTDOWN_PROMPT         "Do you want to shutdown?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -749,4 +751,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 5ff6c83..1689e2a 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -665,6 +665,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Do you want to restart the system?"
        IDS_SHUTDOWN_TITLE          "Shutdown"
        IDS_SHUTDOWN_PROMPT         "Do you want to shutdown?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -749,4 +751,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+    
+       IDS_SHLEXEC_NOASSOC         "Er is geen Windows-programma geconfigureerd om dit soort bestanden te openen."
 END
index 90dc27d..f02aa64 100644 (file)
@@ -359,7 +359,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Åpne med"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -668,6 +668,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Vil du starte datamaskinen på nytt?"
        IDS_SHUTDOWN_TITLE          "Avslutt"
        IDS_SHUTDOWN_PROMPT         "Vil du slå av datamaskinen?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start-meny\\Programmer"
@@ -750,6 +752,8 @@ BEGIN
        IDS_FONTS                   "Skrifttyper"
        IDS_INSTALLNEWFONT          "Installere nye skrifttyper..."
 
-        IDS_DEFAULT_CLUSTER_SIZE    "Standard tildelingsstørrelse"
+       IDS_DEFAULT_CLUSTER_SIZE    "Standard tildelingsstørrelse"
        IDS_COPY_OF                 "Copy of"
+    
+       IDS_SHLEXEC_NOASSOC         "Intet Windows-program er satt opp til å åpne denne filtypen."
 END
index b6d33a6..c9a4d40 100644 (file)
@@ -17,7 +17,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
  * ReactOS shell32 fork translation updated by Caemyr -
- * - Olaf Siejka (Jan,Mar,Apr,Jul, Aug 2008)
+ * - Olaf Siejka (Jan,Mar,Apr,Jul, Aug 2008; Apr, 2010)
  * Use ReactOS forum PM or IRC to contact me
  * http://www.reactos.org
  * IRC: irc.freenode.net #reactos-pl;
@@ -365,7 +365,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Otwórz za pomoc¹"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -672,6 +672,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Czy chcesz zrestartowaæ system?"
        IDS_SHUTDOWN_TITLE          "Wy³¹cz"
        IDS_SHUTDOWN_PROMPT         "Czy chcesz wy³¹czyæ system?"
+       IDS_LOGOFF_TITLE            "Wyloguj"
+       IDS_LOGOFF_PROMPT           "Czy chcesz siê wylogowaæ z systemu?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Menu Start\\Programy"
@@ -756,4 +758,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Domy\9clny rozmiar jednostki alokacji"
        IDS_COPY_OF                 "Kopia"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 048d4c3..7679014 100644 (file)
@@ -360,7 +360,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -667,6 +667,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Você quer simular a reinicialização do Windows?"
        IDS_SHUTDOWN_TITLE          "Desligar"
        IDS_SHUTDOWN_PROMPT         "Você quer finalizar a sessão no Wine?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Menu Iniciar\\Programas"
@@ -751,4 +753,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC     "Nici un program Windows nu este configurat sa deschida fi?iere de acest tip."
 END
index c20e670..2d99ca4 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright 1998 Juergen Schmied
  * Copyright 2003 Marcelo Duarte
  * Copyright 2006-2007 Américo José Melo
+ * Copyright 2010 Manuel D V Silva
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -66,27 +67,27 @@ MENU_SHV_FILE MENU DISCARDABLE
 BEGIN
        POPUP ""
        BEGIN
-               MENUITEM "E&xplore",             FCIDM_SHVIEW_EXPLORE
-               MENUITEM "&Open",                FCIDM_SHVIEW_OPEN
+               MENUITEM "E&xplorador",             FCIDM_SHVIEW_EXPLORE
+               MENUITEM "&Abrir",                FCIDM_SHVIEW_OPEN
                MENUITEM SEPARATOR
-               MENUITEM "C&ut",                 FCIDM_SHVIEW_CUT
-               MENUITEM "&Copy",                FCIDM_SHVIEW_COPY
+               MENUITEM "C&ortar",                 FCIDM_SHVIEW_CUT
+               MENUITEM "&Copiar",                FCIDM_SHVIEW_COPY
                MENUITEM SEPARATOR
-               MENUITEM "Create &Link",         FCIDM_SHVIEW_CREATELINK
-               MENUITEM "&Delete",              FCIDM_SHVIEW_DELETE
-               MENUITEM "&Rename",              FCIDM_SHVIEW_RENAME
+               MENUITEM "Criar &Link",         FCIDM_SHVIEW_CREATELINK
+               MENUITEM "&Apagar",              FCIDM_SHVIEW_DELETE
+               MENUITEM "&Renomear",              FCIDM_SHVIEW_RENAME
                MENUITEM SEPARATOR
-               MENUITEM "&Properties",          FCIDM_SHVIEW_PROPERTIES
+               MENUITEM "&Propriadades",          FCIDM_SHVIEW_PROPERTIES
        END
 END
 
 SHBRSFORFOLDER_MSGBOX DIALOGEX LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192
 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
-CAPTION "Browse for Folder"
+CAPTION "Procurar Pastas"
 FONT 8, "MS Shell Dlg"
 BEGIN
        DEFPUSHBUTTON "OK", 1, 60, 175, 60, 15, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
-       PUSHBUTTON "Cancel", 2, 125, 175, 60, 15, WS_GROUP | WS_TABSTOP
+       PUSHBUTTON "Cancelar", 2, 125, 175, 60, 15, WS_GROUP | WS_TABSTOP
        LTEXT "", IDD_TITLE, 4, 4, 180, 12
        LTEXT "", IDD_STATUS, 4, 25, 180, 12
        CONTROL "", IDD_TREEVIEW, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_TABSTOP, 4, 40, 180, 120
@@ -94,28 +95,28 @@ END
 
 SHNEWBRSFORFOLDER_MSGBOX DIALOGEX LOADONCALL MOVEABLE DISCARDABLE 15, 40, 218, 196
 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
-CAPTION "Browse for Folder"
+CAPTION "Procurar Pastas"
 FONT 8, "MS Shell Dlg"
 BEGIN
        LTEXT "", IDD_TITLE, 10, 8, 198, 24
        LTEXT "", IDD_STATUS, 10, 25, 198, 12
-       LTEXT "Folder:", IDD_FOLDER, 10, 152, 40, 12
+       LTEXT "Pasta:", IDD_FOLDER, 10, 152, 40, 12
        CONTROL "", IDD_TREEVIEW, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_TABSTOP, 12, 38, 194, 105
        EDITTEXT IDD_FOLDERTEXT, 46, 150, 160, 14, WS_BORDER | WS_GROUP | WS_TABSTOP
-       PUSHBUTTON "&Make New Folder", IDD_MAKENEWFOLDER, 12, 174, 77, 14, WS_GROUP | WS_TABSTOP
+       PUSHBUTTON "&Criar Nova Pasta", IDD_MAKENEWFOLDER, 12, 174, 77, 14, WS_GROUP | WS_TABSTOP
        DEFPUSHBUTTON "OK", IDOK, 102, 174, 50, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
-       PUSHBUTTON "Cancel", IDCANCEL, 156, 174, 50, 14, WS_GROUP | WS_TABSTOP
+       PUSHBUTTON "Cancelar", IDCANCEL, 156, 174, 50, 14, WS_GROUP | WS_TABSTOP
 END
 
 SHELL_YESTOALL_MSGBOX DIALOGEX 200, 100, 280, 90
 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
-CAPTION "Message"
+CAPTION "Mensagem"
 FONT 8, "MS Shell Dlg"
 BEGIN
-       DEFPUSHBUTTON "&Yes", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP
-       PUSHBUTTON "Yes to &all", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP
-       PUSHBUTTON "&No", IDNO, 162, 69, 53, 14, WS_GROUP | WS_TABSTOP
-       PUSHBUTTON "&Cancel", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP
+       DEFPUSHBUTTON "&Sim", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP
+       PUSHBUTTON "Sim para &todos", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP
+       PUSHBUTTON "&Não", IDNO, 162, 69, 53, 14, WS_GROUP | WS_TABSTOP
+       PUSHBUTTON "&Cancelar", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP
        ICON "", IDD_ICON, 10, 10, 16, 16
        LTEXT "", IDD_MESSAGE, 40, 10, 238, 52, 0
 END
@@ -127,14 +128,14 @@ FONT 8, "MS Shell Dlg"
 BEGIN
        ICON "", IDC_SHELL_ABOUT_ICON, 7, 55, 21, 20
        LTEXT "", IDC_SHELL_ABOUT_APPNAME, 35, 55, 200, 10
-       LTEXT "Version " KERNEL_VERSION_STR " (" KERNEL_VERSION_BUILD_STR ")", IDC_STATIC, 35, 65, 235, 10
+       LTEXT "Versão " KERNEL_VERSION_STR " (" KERNEL_VERSION_BUILD_STR ")", IDC_STATIC, 35, 65, 235, 10
        LTEXT REACTOS_DEFAULT_STR_LEGAL_COPYRIGHT, IDC_STATIC, 35, 75, 210, 10
        LTEXT "", IDC_SHELL_ABOUT_OTHERSTUFF, 35, 90, 180, 20
-       LTEXT "This ReactOS version is registered to:", IDC_STATIC, 35, 115, 180, 10
+       LTEXT "Esta versão do ReactOS é registado a:", IDC_STATIC, 35, 115, 180, 10
        LTEXT "", IDC_SHELL_ABOUT_REG_USERNAME, 45, 125, 180, 10
        LTEXT "", IDC_SHELL_ABOUT_REG_ORGNAME, 45, 135, 180, 10
        LTEXT "", IDC_STATIC, 35, 147, 235, 1, SS_ETCHEDHORZ
-       LTEXT "Installed physical memory:", IDC_STATIC, 35, 152, 130, 10
+       LTEXT "Memória física instalada:", IDC_STATIC, 35, 152, 130, 10
        LTEXT "", IDC_SHELL_ABOUT_PHYSMEM, 167, 152, 88, 10
        DEFPUSHBUTTON "OK", IDOK, 220, 178, 50, 14
        
@@ -155,7 +156,7 @@ CAPTION ""
 FONT 8, "MS Shell Dlg"
 BEGIN
        ICON "", 12297, 7, 11, 18, 20, WS_VISIBLE
-       LTEXT "Digite o nome do programa, pasta, documento, ou endereço Internet, que o Wine irá abrí-lo.", 12289, 36, 11, 182, 18
+       LTEXT "Digite o nome do programa, pasta, documento, ou endereço Internet, que o ReactOS irá abrí-lo.", 12289, 36, 11, 182, 18
        LTEXT "&Abrir:", 12305, 7, 39, 24, 10
        CONTROL "", 12298, "COMBOBOX", WS_TABSTOP | WS_GROUP | WS_VSCROLL | WS_VISIBLE |  CBS_AUTOHSCROLL | CBS_DROPDOWN, 36, 37, 183, 100
        DEFPUSHBUTTON "OK", IDOK, 62, 63, 50, 14, WS_TABSTOP
@@ -165,156 +166,156 @@ END
 
 SHELL_GENERAL_SHORTCUT_DLG DIALOGEX 0, 0, 235, 215
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Shortcut"
+CAPTION "Atalho"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
        ICON "", 14000, 10, 4, 30, 30, WS_VISIBLE
-       LTEXT "Target type:", 14004, 8, 38, 64, 10
+       LTEXT "Tipo de destino:", 14004, 8, 38, 64, 10
        LTEXT "", 14005, 78, 38, 142, 10
-       LTEXT "Target location:", 14006, 8, 58, 64, 10
+       LTEXT "Localização do destino:", 14006, 8, 58, 64, 10
        LTEXT "", 14007, 79, 58, 141, 10
-       LTEXT "Target:", 14008, 8, 77, 45, 10
+       LTEXT "Destino:", 14008, 8, 77, 45, 10
        EDITTEXT 14009, 79, 75, 150, 14, ES_AUTOHSCROLL
-       LTEXT "&Start in:", 14010, 8, 96, 57, 10
+       LTEXT "&Iniciar em:", 14010, 8, 96, 57, 10
        EDITTEXT 14011, 79, 94, 150, 14, ES_AUTOHSCROLL
-       LTEXT "Shortcut &key:", 14014, 8, 115, 57, 10
+       LTEXT "&Tecla de Atalho:", 14014, 8, 115, 57, 10
        EDITTEXT 14015, 79, 112, 150, 14, ES_LEFT
-       LTEXT "Run:", 14016, 8, 134, 57, 10
+       LTEXT "Executar:", 14016, 8, 134, 57, 10
        EDITTEXT 14017, 79, 131, 150, 14, ES_AUTOHSCROLL
-       LTEXT "C&omment:", 14018, 8, 152, 57, 10
+       LTEXT "C&omemntário:", 14018, 8, 152, 57, 10
        EDITTEXT 14019, 79, 149, 150, 14, ES_AUTOHSCROLL
-       PUSHBUTTON "&Find Target...", 14020, 9, 172, 70, 14, ES_LEFT
-       PUSHBUTTON "&Change Icon...", 14021, 84, 172, 70, 14, ES_LEFT
-       PUSHBUTTON "A&dvanced...", 14022, 159, 172, 70, 14, ES_LEFT
+       PUSHBUTTON "&Localizar Destino...", 14020, 9, 172, 70, 14, ES_LEFT
+       PUSHBUTTON "&Trocar Icon...", 14021, 84, 172, 70, 14, ES_LEFT
+       PUSHBUTTON "A&vançado...", 14022, 159, 172, 70, 14, ES_LEFT
 END
 
 SHELL_EXTENDED_SHORTCUT_DLG DIALOGEX 0, 0, 230, 150
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
-CAPTION "Extended Properties"
+CAPTION "Propriedades Avançadas"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
-       LTEXT "Choose the advanced properties you want for this shortcut.", -1, 5, 30, 210, 10
-       CHECKBOX "Run with different credentials", 14000, 25, 50, 150, 10
-       LTEXT "This option can allow you to run the this shortcut as another user, or continue as yourself while protecting your computer and data from unauthorized program activity.", -1, 50, 60, 175, 40
-       CHECKBOX "Run in seperate memory space", 14001, 25, 100, 90, 10, WS_DISABLED
+       LTEXT "Escolha as propriedades avançadas que quer para este atalho.", -1, 5, 30, 210, 10
+       CHECKBOX "Executar com diferentes credenciais", 14000, 25, 50, 150, 10
+       LTEXT "Esta opção permite executar este atalho como outro utilizador, ou continue com a sua conta enquanto protege o seu computador e dados contra actividade de programas não autorizados.", -1, 50, 60, 175, 40
+       CHECKBOX "Executar num espaço de memória separada", 14001, 25, 100, 90, 10, WS_DISABLED
        PUSHBUTTON "OK", 1, 63, 124, 50, 15, WS_VISIBLE
-       PUSHBUTTON "Abort", 2, 120, 124, 50, 15, WS_VISIBLE
+       PUSHBUTTON "Abortar", 2, 120, 124, 50, 15, WS_VISIBLE
 END
 
 SHELL_FOLDER_GENERAL_DLG DIALOGEX 0, 0, 240, 205
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "General"
+CAPTION "Geral"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
        ICON "", 14000, 10, 3, 30, 30, WS_VISIBLE
        EDITTEXT 14001, 70, 9, 158, 14, ES_LEFT | ES_READONLY
-       LTEXT "Type of file:", 14004, 8, 35, 50, 10
-       LTEXT "Folder", 14005, 68, 35, 160, 10
-       LTEXT "Location:", 14006, 8, 53, 50, 10
+       LTEXT "Tipo de ficheiro:", 14004, 8, 35, 50, 10
+       LTEXT "Pasta", 14005, 68, 35, 160, 10
+       LTEXT "Localização:", 14006, 8, 53, 50, 10
        LTEXT "", 14007, 68, 53, 315, 10
-       LTEXT "Size:", 14008, 8, 72, 45, 10
+       LTEXT "Tamanho:", 14008, 8, 72, 45, 10
        LTEXT "", 14009, 68, 72, 315, 10
-       LTEXT "Contains:", 14010, 8, 93, 45, 10
+       LTEXT "Contém:", 14010, 8, 93, 45, 10
        LTEXT "", 14011, 68, 93, 160, 10
-       LTEXT "Created:", 14014, 8, 118, 45, 10
+       LTEXT "Criado:", 14014, 8, 118, 45, 10
        LTEXT "", 14015, 68, 118, 160, 10
-       AUTOCHECKBOX "&Read-only", 14021, 45, 150, 67, 10
-       AUTOCHECKBOX "&Hidden", 14022, 126, 150, 50, 10
+       AUTOCHECKBOX "&Sómente de Leitura", 14021, 45, 150, 67, 10
+       AUTOCHECKBOX "&Escondido", 14022, 126, 150, 50, 10
 END
 
 SHELL_FILE_GENERAL_DLG DIALOGEX 0, 0, 240, 205
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "General"
+CAPTION "geral"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
        ICON "", 14000, 10, 3, 30, 30, WS_VISIBLE
        EDITTEXT 14001, 70, 9, 158, 14, ES_LEFT | ES_READONLY
-       LTEXT "Type of file:", 14004, 8, 35, 50, 10
-       LTEXT "File", 14005, 68, 35, 160, 10
-       LTEXT "Opens with:", 14006, 8, 53, 50, 10
+       LTEXT "Tipo de Ficheiro:", 14004, 8, 35, 50, 10
+       LTEXT "Ficheiro", 14005, 68, 35, 160, 10
+       LTEXT "Abre com::", 14006, 8, 53, 50, 10
        LTEXT "", 14007, 68, 53, 160, 10
-       LTEXT "Location:", 14008, 8, 72, 45, 10
+       LTEXT "Localização:", 14008, 8, 72, 45, 10
        LTEXT "", 14009, 68, 72, 315, 10
-       LTEXT "Size:", 14010, 8, 93, 45, 10
+       LTEXT "Tamanho:", 14010, 8, 93, 45, 10
        LTEXT "", 14011, 68, 93, 160, 10
-       LTEXT "Created:", 14014, 8, 118, 45, 10
+       LTEXT "Criado:", 14014, 8, 118, 45, 10
        LTEXT "", 14015, 68, 118, 160, 10
-       LTEXT "Modified:", 14016, 8, 140, 45, 10
+       LTEXT "Modificado:", 14016, 8, 140, 45, 10
        LTEXT "", 14017, 68, 140, 160, 10
-       LTEXT "Accessed:", 14018, 8, 160, 45, 10
+       LTEXT "Acedido:", 14018, 8, 160, 45, 10
        LTEXT "", 14019, 68, 160, 160, 10
-       LTEXT "Attributes:", 14020, 8, 189, 45, 10
-       CHECKBOX "&Read-only", 14021, 58, 189, 67, 10
-       CHECKBOX "&Hidden", 14022, 126, 189, 50, 10
-       CHECKBOX "&Archive", 14023, 181, 189, 49, 10
+       LTEXT "propriedades:", 14020, 8, 189, 45, 10
+       CHECKBOX "&Somente de Leitura", 14021, 58, 189, 67, 10
+       CHECKBOX "&Oculto", 14022, 126, 189, 50, 10
+       CHECKBOX "&Arquivo", 14023, 181, 189, 49, 10
 END
 
 SHELL_FILE_VERSION_DLG DIALOGEX 0, 0, 235, 215
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Version"
+CAPTION "Versão"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
-       LTEXT "File version: ", 14000, 10, 10, 55, 10
+       LTEXT "Versão do Ficheiro: ", 14000, 10, 10, 55, 10
        LTEXT "", 14001, 77, 10, 152, 10
-       LTEXT "Description: ", 14002, 10, 27, 45, 10
+       LTEXT "Descrição: ", 14002, 10, 27, 45, 10
        LTEXT "", 14003, 77, 27, 152, 10
        LTEXT "Copyright: ", 14004, 10, 46, 66, 10
        LTEXT "", 14005, 77, 46, 152, 10
-       GROUPBOX "Other version information: ", 14006, 6, 70, 222, 115
-       LTEXT "Item name: ", 14007, 13, 82, 50, 10
-       LTEXT "Value: ", 14008, 112, 82, 45, 10
+       GROUPBOX "Outras informações da versão: ", 14006, 6, 70, 222, 115
+       LTEXT "Nome do Item: ", 14007, 13, 82, 50, 10
+       LTEXT "Valor: ", 14008, 112, 82, 45, 10
        LISTBOX 14009, 12, 94, 94, 83, LBS_STANDARD | WS_TABSTOP | LBS_NOTIFY
        EDITTEXT 14010, 112, 93, 109, 83, ES_LEFT | WS_BORDER | WS_VSCROLL | WS_GROUP | ES_MULTILINE | ES_READONLY
 END
 
 DRIVE_GENERAL_DLG DIALOGEX 0, 0, 240, 230
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "General"
+CAPTION "Geral"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
        EDITTEXT 14000, 40, 20, 190, 14, ES_LEFT|WS_BORDER|WS_GROUP
-       LTEXT "Type:", -1, 15, 55, 40, 10
+       LTEXT "Tipo:", -1, 15, 55, 40, 10
        LTEXT "", 14001, 110, 55, 100, 10
 
-       LTEXT "File system:", -1, 15, 70, 100, 10
+       LTEXT "Sistema de Ficheiros:", -1, 15, 70, 100, 10
        LTEXT "", 14002, 110, 70, 100, 10
 
        CONTROL "", 14013, "Static", SS_NOTIFY | SS_SUNKEN | SS_OWNERDRAW, 5, 90, 10, 10
-       LTEXT "Used space:", -1, 25, 90, 120, 10
+       LTEXT "Espaço utilizado:", -1, 25, 90, 120, 10
        LTEXT "", 14003, 110, 90, 120, 10
        LTEXT "", 14004, 200, 90, 40, 10
 
        CONTROL "", 14014, "Static", SS_NOTIFY | SS_SUNKEN | SS_OWNERDRAW, 5, 105, 10, 10
-       LTEXT "Free space:", -1, 25, 105, 70, 10
+       LTEXT "Espaço livre:", -1, 25, 105, 70, 10
        LTEXT "", 14005, 110, 105, 120, 10
        LTEXT "", 14006, 200, 105, 40, 10
 
-       LTEXT "Capacity:", -1, 25, 125, 80, 10
+       LTEXT "Capacidade:", -1, 25, 125, 80, 10
        LTEXT "", 14007, 110, 125, 120, 10
        LTEXT "", 14008, 200, 125, 40, 10
 
        CONTROL "", 14015, "Static", SS_NOTIFY | SS_SUNKEN | SS_OWNERDRAW, 20, 140, 200, 20
 
-       LTEXT "Drive %s", 14009, 100, 170, 40, 10
-       PUSHBUTTON "Disk Cleanup", 14010, 180, 175, 50, 15, WS_TABSTOP
-       CHECKBOX "Compress drive to save disk space", 14011, 15, 205, 180, 10, WS_DISABLED
-       CHECKBOX "Allow Indexing Service to index this disk for fast file searching", 14012, 15, 220, 200, 10, WS_DISABLED
+       LTEXT "Disco %s", 14009, 100, 170, 40, 10
+       PUSHBUTTON "Limpeza do Disco", 14010, 180, 175, 50, 15, WS_TABSTOP
+       CHECKBOX "Comprimir unidade para libertar espaço no disco", 14011, 15, 205, 180, 10, WS_DISABLED
+       CHECKBOX "permitir indexar este disco para acelerar a procura de ficheiros", 14012, 15, 220, 200, 10, WS_DISABLED
 END
 
 DRIVE_EXTRA_DLG DIALOGEX 0, 0, 240, 230
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Tools"
+CAPTION "Ferramentas"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
-       GROUPBOX "Error-checking", -1, 5, 5, 230, 60
-       LTEXT "This option will check the volume for\nerrors.", -1, 40, 25, 160, 20
-       PUSHBUTTON "Check Now...", 14000, 130, 45, 90, 15, WS_TABSTOP
-       GROUPBOX "Defragmentation", -1, 5, 65, 230, 60
-       LTEXT "This option will defragment files on the volume", -1, 40, 85, 160, 20
-       PUSHBUTTON "Defragment Now...", 14001, 130, 105, 90, 15, WS_TABSTOP
-       GROUPBOX "Backup", -1, 5, 130, 230, 60
-       LTEXT "This option will back up files on the volume.", -1, 40, 150, 160, 20
-       PUSHBUTTON "Backup Now...", 14002, 130, 170, 90, 15, WS_TABSTOP
+       GROUPBOX "Verificar por erros...", -1, 5, 5, 230, 60
+       LTEXT "Esta opção vai verificar o volume por erros.", -1, 40, 25, 160, 20
+       PUSHBUTTON "Verificar agora...", 14000, 130, 45, 90, 15, WS_TABSTOP
+       GROUPBOX "Desfragmentação", -1, 5, 65, 230, 60
+       LTEXT "Esta opção vai desfragmentar os ficheiros no volume", -1, 40, 85, 160, 20
+       PUSHBUTTON "Defragmentar Agora...", 14001, 130, 105, 90, 15, WS_TABSTOP
+       GROUPBOX "Cópia de segurança", -1, 5, 130, 230, 60
+       LTEXT "Esta opção vai criar os ficheiros do volume.", -1, 40, 150, 160, 20
+       PUSHBUTTON "Executar Cópia de Segurança...", 14002, 130, 170, 90, 15, WS_TABSTOP
 END
 
 DRIVE_HARDWARE_DLG DIALOGEX 0, 0, 240, 230
@@ -326,151 +327,151 @@ END
 
 RUN_AS_DIALOG DIALOGEX 0, 0, 240, 190
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Run As"
+CAPTION "Executar Como..."
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
-       LTEXT "Which user account do you want to use to run this program?", -1, 10, 20, 220, 20
-       CHECKBOX "Current User %s", 14000, 10, 45, 150, 10
-       LTEXT "Protect my computer and data from unauthorized program activity", -1, 25, 57, 200, 10, WS_DISABLED
-       CHECKBOX "This option can prevent computer viruses from harming your computer or personal data, but selecting it might cause the program to function improperly.", 14001, 25, 68, 200, 30, WS_DISABLED | BS_MULTILINE
-       CHECKBOX "The following user:", 14002, 10, 100, 90, 10
-       LTEXT "User name:", -1, 20, 118, 54, 10
+       LTEXT "Que conta de utilizador quer utilizar para executar este programa?", -1, 10, 20, 220, 20
+       CHECKBOX "Utilizador actual %s", 14000, 10, 45, 150, 10
+       LTEXT "Proteger o meu computador e dados de actividade de programas não autoridados.", -1, 25, 57, 200, 10, WS_DISABLED
+       CHECKBOX "Esta opção pode prevenir a acção de virus no computador,mas seleccionando-a pode levar a que alguns programas funcionem incorrectamente.", 14001, 25, 68, 200, 30, WS_DISABLED | BS_MULTILINE
+       CHECKBOX "O seguinte utilizador:", 14002, 10, 100, 90, 10
+       LTEXT "Nome do utilizador:", -1, 20, 118, 54, 10
        COMBOBOX 14003, 75, 115, 100, 15, CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP
 
        PUSHBUTTON "...", 14004, 180, 115, 30, 14, WS_TABSTOP
-       LTEXT "Password:", -1, 20, 143, 53, 10
+       LTEXT "Palavra-passe:", -1, 20, 143, 53, 10
        EDITTEXT 14005, 74, 140, 100, 14, ES_LEFT | WS_BORDER | WS_GROUP
        PUSHBUTTON "...", 14006, 180, 140, 30, 14, WS_TABSTOP
        PUSHBUTTON "OK", 14007, 57, 170, 60, 14, WS_TABSTOP
-       PUSHBUTTON "Cancel", 14008, 122, 170, 60, 14, WS_TABSTOP
+       PUSHBUTTON "Cancelar", 14008, 122, 170, 60, 14, WS_TABSTOP
 END
 
 BITBUCKET_PROPERTIES_DLG DIALOGEX 0, 0, 240, 190
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Recycle Bin Properties"
+CAPTION "propriedades da Reciclagem"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
        CONTROL "", 14000, "SysListView32", LVS_REPORT | LVS_SHAREIMAGELISTS | WS_BORDER | WS_TABSTOP, 10, 10, 220, 50
-       GROUPBOX "Settings for selected location", -1, 10, 72, 220, 70
-       RADIOBUTTON "&Custom size:", 14001, 20, 90, 80, 10, WS_TABSTOP
+       GROUPBOX "propriedades para as localizações seleccionadas", -1, 10, 72, 220, 70
+       RADIOBUTTON "&Tamanho personalizado:", 14001, 20, 90, 80, 10, WS_TABSTOP
        EDITTEXT 14002, 106, 87, 50, 14, WS_TABSTOP | ES_NUMBER
-       LTEXT "M&aximum size(MB):", -1, 20, 105, 70, 10
-       RADIOBUTTON "Do not move files to the &Recycle Bin. Remove files immediately when deleted.", 14003, 20, 117, 170, 20, BS_MULTILINE | WS_TABSTOP
-       AUTOCHECKBOX "&Display delete confirmation dialog", 14004, 20, 155, 140, 10, WS_TABSTOP
+       LTEXT "Tamanho M&áximo(MB):", -1, 20, 105, 70, 10
+       RADIOBUTTON "Não mover os ficheiros para a &Reciclagem. Apagá-los definitivamente.", 14003, 20, 117, 170, 20, BS_MULTILINE | WS_TABSTOP
+       AUTOCHECKBOX "&Mostrar ecrân de confirmação de eliminação", 14004, 20, 155, 140, 10, WS_TABSTOP
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
-CAPTION "Open With"
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
+CAPTION "Abre com..."
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
        ICON IDI_SHELL_OPEN_WITH, -1, 8, 12, 21, 20
-       LTEXT "Choose the program you want to use to open this file:", -1, 44, 12, 211, 10
-       LTEXT "File:    ", 14001, 44, 25, 188, 10
-       GROUPBOX "&Programs", -1, 7, 42, 249, 187
+       LTEXT "Escolha o programa que quer utilizar para abrir este ficheiro:", -1, 44, 12, 211, 10
+       LTEXT "Ficheiro:    ", 14001, 44, 25, 188, 10
+       GROUPBOX "&Programas", -1, 7, 42, 249, 187
         LISTBOX 14002, 16 ,57, 230, 130, LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP, WS_EX_STATICEDGE
-       AUTOCHECKBOX "&Always use the selected program to open this kind of file", 14003, 20, 193, 225, 10
-       PUSHBUTTON "&Browse...", 14004, 198, 207, 50, 14
+       AUTOCHECKBOX "&Utilizar sempre o programa seleccionado para abrir este tipo de ficheiros", 14003, 20, 193, 225, 10
+       PUSHBUTTON "&Seleccione...", 14004, 198, 207, 50, 14
        PUSHBUTTON "OK", 14005, 150, 236, 50, 14
-       PUSHBUTTON "Cancel", 14006, 206, 236, 50, 14
+       PUSHBUTTON "Cancelar", 14006, 206, 236, 50, 14
 END
 
 FOLDER_OPTIONS_GENERAL_DLG DIALOGEX 0, 0, 264, 256
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
-CAPTION "General"
+CAPTION "Geral"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
-       GROUPBOX "Tasks", -1, 7, 10, 249, 45
+       GROUPBOX "Tarefas", -1, 7, 10, 249, 45
        ICON "", 30109, 14, 25, 21, 20, SS_REALSIZECONTROL
-       AUTORADIOBUTTON "Show common tasks in &folders", 14001, 40, 25, 120, 10, WS_TABSTOP | WS_GROUP
-       AUTORADIOBUTTON "Use ReactOS class&ic folders", 14002, 40, 37, 120, 10, WS_TABSTOP | WS_GROUP
-       GROUPBOX "Browse folders", -1, 7, 60, 249, 45, WS_TABSTOP
+       AUTORADIOBUTTON "Mostrar tarefas comuns nas &pastas", 14001, 40, 25, 120, 10, WS_TABSTOP | WS_GROUP
+       AUTORADIOBUTTON "Utilizar pastas class&icas ReactOS", 14002, 40, 37, 120, 10, WS_TABSTOP | WS_GROUP
+       GROUPBOX "Procurar pastas", -1, 7, 60, 249, 45, WS_TABSTOP
        ICON "", 30110, 14, 70, 21, 20, SS_REALSIZECONTROL
-       AUTORADIOBUTTON "Open each folder in the sa&me window", 14004, 40, 70, 140, 10, WS_TABSTOP | WS_GROUP
-       AUTORADIOBUTTON "Open each folder in its own &window", 14005, 40, 82, 140, 10, WS_TABSTOP | WS_GROUP
-       GROUPBOX "Click items as follows", -1, 7, 110, 249, 60
+       AUTORADIOBUTTON "Abrir cada pasta na &mesma janela", 14004, 40, 70, 140, 10, WS_TABSTOP | WS_GROUP
+       AUTORADIOBUTTON "Abrir cada pasta na sua &janela", 14005, 40, 82, 140, 10, WS_TABSTOP | WS_GROUP
+       GROUPBOX "Seleccione a seguinte opção", -1, 7, 110, 249, 60
        ICON "", 30111, 14, 120, 21, 20, SS_REALSIZECONTROL
-       AUTORADIOBUTTON "&Single-click to open an item (point to select)", 14007, 40, 120, 170, 10, WS_TABSTOP | WS_GROUP
-       AUTORADIOBUTTON "Underline icon titles consistent with my &browser", 14008, 50, 132, 170, 10, WS_TABSTOP | WS_GROUP
-       AUTORADIOBUTTON "Underline icon titles only when I &point at them", 14009, 50, 144, 170, 10, WS_TABSTOP | WS_GROUP
-       AUTORADIOBUTTON "&Double-click to open an item (single-click to select)", 14010, 40, 156, 170, 10, WS_TABSTOP | WS_GROUP
-       PUSHBUTTON "&Restore Defaults", 14011, 180, 180, 60, 14, WS_TABSTOP
+       AUTORADIOBUTTON "&Click simples para abrir um item", 14007, 40, 120, 170, 10, WS_TABSTOP | WS_GROUP
+       AUTORADIOBUTTON "Sublinhar os títulos dos ícones mantendo o aspecto do &browser", 14008, 50, 132, 170, 10, WS_TABSTOP | WS_GROUP
+       AUTORADIOBUTTON "Sublinhar os títulos dos ícones apenas quando &aponto para eles", 14009, 50, 144, 170, 10, WS_TABSTOP | WS_GROUP
+       AUTORADIOBUTTON "&Duplo-click para abrir um item (um click para seleccionar)", 14010, 40, 156, 170, 10, WS_TABSTOP | WS_GROUP
+       PUSHBUTTON "&Restaurar valores por defeito", 14011, 180, 180, 60, 14, WS_TABSTOP
 END
 
 FOLDER_OPTIONS_VIEW_DLG DIALOGEX 0, 0, 264, 256
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
-CAPTION "View"
+CAPTION "Ver"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
-GROUPBOX "Folder views", -1, 7, 10, 249, 60
+GROUPBOX "Vistas das Pastas", -1, 7, 10, 249, 60
 //ICON
-LTEXT "You can apply the view(such as Details or Tiles) that\nyou are using for this folder to all folders.", -1, 60, 20, 180, 20
-PUSHBUTTON "Apply to A&ll Folders", 14001, 60, 50, 80, 14, WS_TABSTOP
-PUSHBUTTON "&Reset All Folders", 14002, 150, 50, 80, 14, WS_TABSTOP
-LTEXT "Advanced settings:", -1, 7, 80, 100, 10
+LTEXT "Pode aplicar a vista (como detalhes ou títulos) que\nestá a usar para esta pasta para todas as pastas.", -1, 60, 20, 180, 20
+PUSHBUTTON "Applicar a T&odas as Pastas", 14001, 60, 50, 80, 14, WS_TABSTOP
+PUSHBUTTON "&Reiniciar todas as Pastas", 14002, 150, 50, 80, 14, WS_TABSTOP
+LTEXT "Definições avançadas:", -1, 7, 80, 100, 10
 CONTROL "", 14003, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | WS_BORDER | WS_TABSTOP, 7, 90, 249, 120
-PUSHBUTTON "Restore &Defaults", 14004, 180, 210, 80, 14, WS_TABSTOP
+PUSHBUTTON "Restaurar valores por &Defeito", 14004, 180, 210, 80, 14, WS_TABSTOP
 END
 
 FOLDER_OPTIONS_FILETYPES_DLG DIALOGEX 0, 0, 264, 256
 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
-CAPTION "File Types"
+CAPTION "Tipos de Ficheiros"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
-LTEXT "Registered file &types:", -1, 7, 10, 70, 10
+LTEXT "&Tipos de ficheiros registados:", -1, 7, 10, 70, 10
 CONTROL "", 14000, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHAREIMAGELISTS | WS_BORDER | WS_TABSTOP, 7, 20, 249, 80
-PUSHBUTTON "&New", 14001, 120, 110, 50, 14, WS_TABSTOP
-PUSHBUTTON "&Delete", 14002, 180, 110, 50, 14, WS_TABSTOP
-GROUPBOX "Details for '%s' extension", 14003, 7, 130, 249, 70
-LTEXT "Opens with:", -1, 12, 140, 40, 10
+PUSHBUTTON "&Novo", 14001, 120, 110, 50, 14, WS_TABSTOP
+PUSHBUTTON "&Apagar", 14002, 180, 110, 50, 14, WS_TABSTOP
+GROUPBOX "Detalhes para '%s' extensão", 14003, 7, 130, 249, 70
+LTEXT "Abre com:", -1, 12, 140, 40, 10
 //ICON
-LTEXT "Appname", 14005, 100, 140, 40, 10
-PUSHBUTTON "&Change...", 14006, 180, 140, 50, 14, WS_TABSTOP
-LTEXT "Files with extension '%s' are of type '%s'. To\nchange settings that affect all '%s' files, click\nAdvanced.", 14007, 12, 155, 160, 30
-PUSHBUTTON "Ad&vanced", 14008, 180, 175, 50, 14, WS_TABSTOP
+LTEXT "Appnome", 14005, 100, 140, 40, 10
+PUSHBUTTON "&Mudar...", 14006, 180, 140, 50, 14, WS_TABSTOP
+LTEXT "Ficheiros com extensão '%s' são do tipo '%s'. Para\nmudar definições que afectam todos '%s' ficheiros, click\nAvançado.", 14007, 12, 155, 160, 30
+PUSHBUTTON "A&vançado", 14008, 180, 175, 50, 14, WS_TABSTOP
 END
 
 CONFIRM_FILE_REPLACE_DLG DIALOGEX 0, 0, 282, 143
 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION
-CAPTION "Confirm File Replace"
+CAPTION "Confirmar Substituição de Ficheiros"
 FONT 8, "MS Shell Dlg"
 BEGIN
-       DEFPUSHBUTTON "&Yes", IDYES, 20, 122, 60, 14
-       PUSHBUTTON "Yes to &All", 12807, 85, 122, 60, 14
-       PUSHBUTTON "&No", IDNO, 150, 122, 60, 14
-       PUSHBUTTON "Cancel", IDCANCEL, 215, 122, 60, 14
+       DEFPUSHBUTTON "&Sim", IDYES, 20, 122, 60, 14
+       PUSHBUTTON "Sim para &Todos", 12807, 85, 122, 60, 14
+       PUSHBUTTON "&Não", IDNO, 150, 122, 60, 14
+       PUSHBUTTON "Cancelar", IDCANCEL, 215, 122, 60, 14
        ICON 146, -1, 11, 10, 21, 20, SS_REALSIZECONTROL
-       LTEXT "This folder already contains a file named '%2'.", 12291, 44, 10, 231, 22, SS_NOPREFIX
-       LTEXT "This folder already contains a read-only file named '%2'.", 12292, 41, 10, 222, 22, SS_NOPREFIX
-       LTEXT "This folder already contains a system file named '%2'.", 12293, 41, 10, 222, 22, SS_NOPREFIX
-       LTEXT "Would you like to replace the existing file", -1, 44, 35, 228, 10, SS_NOPREFIX
-       LTEXT "(unknown date and size)", 12302, 79, 51, 198, 20, SS_NOPREFIX
+       LTEXT "Esta pasta já contém um ficheiro com o nome '%2'.", 12291, 44, 10, 231, 22, SS_NOPREFIX
+       LTEXT "Esta pasta já contém um ficheiro sómente de leitura com o nome '%2'.", 12292, 41, 10, 222, 22, SS_NOPREFIX
+       LTEXT "Esta pasta já contém um ficheiro de sistema com o nome '%2'.", 12293, 41, 10, 222, 22, SS_NOPREFIX
+       LTEXT "pretende substituir o ficheiro existente", -1, 44, 35, 228, 10, SS_NOPREFIX
+       LTEXT "(data e tamanho desconhecido)", 12302, 79, 51, 198, 20, SS_NOPREFIX
        ICON "", 12300, 50, 49, 21, 20, SS_REALSIZECONTROL
-       LTEXT "with this one?", -1, 44, 75, 228, 10, SS_NOPREFIX
-       LTEXT "(unknown date and size)", 12303, 79, 91, 198, 20, SS_NOPREFIX
+       LTEXT "por este?", -1, 44, 75, 228, 10, SS_NOPREFIX
+       LTEXT "(data e tamanho desconhecido)", 12303, 79, 91, 198, 20, SS_NOPREFIX
        ICON "", 12301, 50, 89, 21, 20, SS_REALSIZECONTROL
 END
 
 LOGOFF_DLG DIALOGEX 0, 0, 190, 60
 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
-CAPTION "Log Off ReactOS"
+CAPTION "Terminar sessão ReactOS"
 FONT 8, "MS Shell Dlg"
 BEGIN
        ICON 45, 14344, 10, 10, 21, 20, SS_REALSIZECONTROL
-       LTEXT "Are you sure you want to log off?", -1, 43, 11, 140, 22
-       DEFPUSHBUTTON "&Log Off", IDOK, 57, 40, 60, 14
-       PUSHBUTTON "Cancel", IDCANCEL, 122, 40, 60, 14
+       LTEXT "Tem a certeza que quer terminar a sessão?", -1, 43, 11, 140, 22
+       DEFPUSHBUTTON "&Terminar a sessão", IDOK, 57, 40, 60, 14
+       PUSHBUTTON "Cancelar", IDCANCEL, 122, 40, 60, 14
 END
 
 DISCONNECT_DLG DIALOGEX 0, 0, 190, 60
 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
-CAPTION "Disconnect ReactOS"
+CAPTION "Encerrar ReactOS"
 FONT 8, "MS Shell Dlg"
 BEGIN
        ICON 49, 14346, 10, 10, 21, 20, SS_REALSIZECONTROL
-       LTEXT "Are you sure you want to disconnect?", -1, 49, 12, 137, 23
-       DEFPUSHBUTTON "&Disconnect", IDOK, 57, 40, 60, 14
-       PUSHBUTTON "Cancel", IDCANCEL, 123, 40, 60, 14
+       LTEXT "Tem a certeza que quer encerrar?", -1, 49, 12, 137, 23
+       DEFPUSHBUTTON "&Encerrar", IDOK, 57, 40, 60, 14
+       PUSHBUTTON "Cancelar", IDCANCEL, 123, 40, 60, 14
 END
 
 AUTOPLAY1_DLG DIALOGEX 0, 0, 227, 218
@@ -478,42 +479,42 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUPWINDOW | WS_VISIBLE | WS_CLIPSIBLIN
 CAPTION "AutoPlay"
 FONT 8, "MS Shell Dlg"
 BEGIN
-       LTEXT "&Select a content type, then choose an action for ReactOS to perform automatically when that type is used in this device:", 1000, 7, 7, 215, 20
+       LTEXT "&Seleccione o tipo de conteúdo, depois escolha uma acção para o RactOS executar automáticamente quando este tipo for usado neste dispositivo:", 1000, 7, 7, 215, 20
        CONTROL "", 1001, "COMBOBOXEX32", WS_TABSTOP | 0x00000043, 7, 27, 212, 200
-       GROUPBOX "Actions", -1, 7, 45, 212, 146
-       AUTORADIOBUTTON "Select an action to &perform:", 1005, 14, 54, 202, 10, WS_GROUP
+       GROUPBOX "Acções", -1, 7, 45, 212, 146
+       AUTORADIOBUTTON "Seleccione uma acção para &executar:", 1005, 14, 54, 202, 10, WS_GROUP
        CONTROL "LIST2", 1002, "SYSLISTVIEW32", WS_BORDER | WS_TABSTOP | 0x0000C04D, 22, 66, 192, 107
-       AUTORADIOBUTTON "Prompt me each time to &choose an action", 1006, 14, 177, 202, 10
-       PUSHBUTTON "&Restore Defaults", 1008, 108, 197, 110, 14, WS_DISABLED
+       AUTORADIOBUTTON "pergunte-me sempre para escolher uma &acção", 1006, 14, 177, 202, 10
+       PUSHBUTTON "&Restaurar valores por defeito", 1008, 108, 197, 110, 14, WS_DISABLED
 END
 
 MIXED_CONTENT1_DLG DIALOGEX 0, 0, 227, 207
 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION
-CAPTION "Mixed Content"
+CAPTION "Conteúdos mistos"
 FONT 8, "MS Shell Dlg"
 BEGIN
        ICON "", 1000, 5, 7, 21, 20
-       LTEXT "This disk or device contains more than one type of content.", 1001, 32, 7, 191, 20
-       LTEXT "What do you want ReactOS to do?", 1002, 32, 31, 188, 8
+       LTEXT "Este disco ou dispositivo contém mais de um tipo de conteúdo.", 1001, 32, 7, 191, 20
+       LTEXT "O que pretende que o ReactOS faça?", 1002, 32, 31, 188, 8
        CONTROL "", 1003, "SYSLISTVIEW32", WS_BORDER | WS_TABSTOP | 0x0000C04D, 32, 43, 188, 139
        DEFPUSHBUTTON "OK", IDOK, 96, 186, 60, 14
-       PUSHBUTTON "Cancel", IDCANCEL, 160, 186, 60, 14
+       PUSHBUTTON "Cancelar", IDCANCEL, 160, 186, 60, 14
 END
 
 MIXED_CONTENT2_DLG DIALOGEX 0, 0, 227, 206
 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION
-CAPTION "Mixed Content"
+CAPTION "Conteúdo misto"
 FONT 8, "MS Shell Dlg"
 BEGIN
        ICON "", 1000, 5, 7, 21, 20
-       LTEXT "ReactOS can perform the same action each time you insert a disk or connect a device with this kind of file:", 1001, 30, 7, 193, 20
+       LTEXT "ReactOS pode executar a mesma acção de cada vez que inserir um disco ou um dispositivo com este tipo de ficheiro:", 1001, 30, 7, 193, 20
        ICON "", 1005, 32, 27, 11, 10, SS_REALSIZECONTROL
        EDITTEXT 1006, 49, 28, 177, 14, ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP
-       LTEXT "What do you want ReactOS to do?", 1002, 32, 41, 190, 8
+       LTEXT "O que pretende que o ReactOS faça?", 1002, 32, 41, 190, 8
        CONTROL "", 1003, "SYSLISTVIEW32", WS_BORDER | WS_TABSTOP | 0x0000C04D, 32, 55, 188, 112
-       AUTOCHECKBOX "Always do the selected action.", 1004, 32, 171, 190, 10
+       AUTOCHECKBOX "Executar sempre a acção seleccionada.", 1004, 32, 171, 190, 10
        DEFPUSHBUTTON "OK", IDOK, 96, 185, 60, 14
-       PUSHBUTTON "Cancel", IDCANCEL, 160, 185, 60, 14
+       PUSHBUTTON "Cancelar", IDCANCEL, 160, 185, 60, 14
 END
 
 AUTOPLAY2_DLG DIALOGEX 0, 0, 227, 181
@@ -522,75 +523,75 @@ CAPTION "Autoplay"
 FONT 8, "MS Shell Dlg"
 BEGIN
        ICON "", 1000, 5, 7, 21, 20
-       LTEXT "ReactOS can perform the same action each time you connect this device.", 1001, 32, 7, 190, 22
-       LTEXT "&What do you want ReactOS to do?", 1002, 32, 31, 190, 8
+       LTEXT "ReactOS pode executar sempre mesma acção de cada vez que inserir um disco ou um dispositivo.", 1001, 32, 7, 190, 22
+       LTEXT "&O que pretende que o ReactOS faça?", 1002, 32, 31, 190, 8
        CONTROL "", 1003, "SYSLISTVIEW32", WS_BORDER | WS_TABSTOP | 0x0000C04D, 32, 43, 187, 96
-       AUTOCHECKBOX "&Always perform the selected action", 1004, 32, 143, 190, 8
+       AUTOCHECKBOX "&Executar sempre a acção seleccionada", 1004, 32, 143, 190, 8
        DEFPUSHBUTTON "OK", IDOK, 94, 160, 60, 14
-       PUSHBUTTON "Cancel", IDCANCEL, 159, 160, 60, 14
+       PUSHBUTTON "Cancelar", IDCANCEL, 159, 160, 60, 14
 END
 
 SHUTDOWN_DLG DIALOGEX 0, 0, 211, 103
 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
-CAPTION "Shut Down ReactOS"
+CAPTION "Encerrar ReactOS"
 FONT 8, "MS Shell Dlg"
 BEGIN
        ICON 8240, -1, 6, 6, 21, 20, SS_REALSIZECONTROL | WS_GROUP
-       LTEXT "What do you want the computer to do?", -1, 39, 7, 167, 10
+       LTEXT "O que pretende aue o computador faça?", -1, 39, 7, 167, 10
        COMBOBOX 8224, 39, 20, 165, 200, CBS_DROPDOWNLIST | WS_VSCROLL
-       LTEXT "Maintains your session, keeping the computer running on low power with data still in memory. The computer wakes up when you press a key or move the mouse.", 8225, 39, 40, 167, 37
+       LTEXT "Manter a sessão, deixando o computador a correr em baixa energia. O computador arranca quando tocar numa tecla ou mover o rato.", 8225, 39, 40, 167, 37
        DEFPUSHBUTTON "OK", 1, 7, 82, 60, 14, WS_GROUP
-       PUSHBUTTON "Cancel", IDCANCEL, 75, 82, 60, 14
-       PUSHBUTTON "&Help", IDHELP, 144, 82, 60, 14
+       PUSHBUTTON "Cancelar", IDCANCEL, 75, 82, 60, 14
+       PUSHBUTTON "&Ajuda", IDHELP, 144, 82, 60, 14
 END
 
 FORMAT_DLG DIALOGEX 50, 50, 184, 218
 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION
-CAPTION "Format"
+CAPTION "Formatar"
 FONT 8, "MS Shell Dlg"
 BEGIN
-       DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14
-       PUSHBUTTON "&Close", IDCANCEL, 118, 198, 60, 14
-       LTEXT "Ca&pacity:", -1, 7, 6, 169, 9
+       DEFPUSHBUTTON "&Iniciar", IDOK, 53, 198, 60, 14
+       PUSHBUTTON "&Fechar", IDCANCEL, 118, 198, 60, 14
+       LTEXT "Ca&pacidade:", -1, 7, 6, 169, 9
        COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP
-       LTEXT "&File system", -1, 7, 35, 170, 9
+       LTEXT "&Sistema de Ficheiros", -1, 7, 35, 170, 9
        COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP
        CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8
-       LTEXT "&Allocation unit size", -1, 7, 64, 170, 9
+       LTEXT "&Tamanho da unidade de alocação", -1, 7, 64, 170, 9
        COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP
-       LTEXT "Volume &label", -1, 7, 93, 170, 9
+       LTEXT "&Nome do Volume ", -1, 7, 93, 170, 9
        EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL
-       GROUPBOX "Format &options", 4610, 7, 121, 170, 49
-       AUTOCHECKBOX "&Quick Format", 28674, 16, 135, 155, 10
-       AUTOCHECKBOX "&Enable Compression", 28675, 16, 152, 155, 10
+       GROUPBOX "&Opções", 4610, 7, 121, 170, 49
+       AUTOCHECKBOX "Formatação &Rápida", 28674, 16, 135, 155, 10
+       AUTOCHECKBOX "&Permitir Compressão", 28675, 16, 152, 155, 10
 END
 
 CHKDSK_DLG DIALOGEX 50, 50, 194, 120
 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION
-CAPTION "Check Disk"
+CAPTION "Verificar Disco"
 FONT 8, "MS Shell Dlg"
 BEGIN
-       DEFPUSHBUTTON "Start", IDOK, 53, 100, 60, 14
-       GROUPBOX "Check disk options", -1, 7, 6, 179, 50
-       PUSHBUTTON "Cancel", IDCANCEL, 118, 100, 60, 14
-       AUTOCHECKBOX "Automatically fix file system errors", 14000, 16, 15, 155, 10
-       AUTOCHECKBOX "&Scan for and attempt recovery of bad sectors", 14001, 16, 30, 165, 10
+       DEFPUSHBUTTON "Iniciar", IDOK, 53, 100, 60, 14
+       GROUPBOX "Opções verificação do disco", -1, 7, 6, 179, 50
+       PUSHBUTTON "Cancelar", IDCANCEL, 118, 100, 60, 14
+       AUTOCHECKBOX "Reparar automáticamente erros nos ficheiros do sistema", 14000, 16, 15, 155, 10
+       AUTOCHECKBOX "&Procurar e tentar reparar sectores danificados", 14001, 16, 30, 165, 10
        CONTROL "", 14002, "MSCTLS_PROGRESS32", 16, 7, 60, 170, 8
        LTEXT "", 14003, 60, 80, 170, 10
 END
 
 IDD_PICK_ICON_DIALOG DIALOGEX 0, 0, 237, 204
 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION
-CAPTION "Change Icon"
+CAPTION "Trocar Icone"
 FONT 8, "MS Shell Dlg", 400, 0, 0x1
 BEGIN
-    LTEXT "Filename:", -1, 7, 14, 208, 10
-    PUSHBUTTON      "Browse...",IDC_BUTTON_PATH, 148, 24,67,14
+    LTEXT "Nome do ficheiro:", -1, 7, 14, 208, 10
+    PUSHBUTTON      "procurar...",IDC_BUTTON_PATH, 148, 24,67,14
     EDITTEXT        IDC_EDIT_PATH, 6, 24, 135, 15, ES_AUTOHSCROLL
     LTEXT "Icons:", -1, 7, 47, 208, 10
     LISTBOX         IDC_PICKICON_LIST,7,57,208,119,LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,WS_EX_STATICEDGE
     DEFPUSHBUTTON   "OK",IDOK, 107, 181,50, 14
-    PUSHBUTTON      "Cancel",IDCANCEL, 167, 181, 50, 14
+    PUSHBUTTON      "Cancelar",IDCANCEL, 167, 181, 50, 14
 END
 
 STRINGTABLE DISCARDABLE
@@ -600,32 +601,32 @@ BEGIN
        IDS_SHV_COLUMN2             "Tamanho"
        IDS_SHV_COLUMN3             "Tipo"
        IDS_SHV_COLUMN4             "Modificado"
-       IDS_SHV_COLUMN5             "Atributos"
+       IDS_SHV_COLUMN5             "propriedades"
        IDS_SHV_COLUMN6             "Tamanho"
        IDS_SHV_COLUMN7             "Disponível"
        IDS_SHV_COLUMN8             "Nome"
        IDS_SHV_COLUMN9             "Comentários"
        IDS_SHV_COLUMN10            "Dono"
        IDS_SHV_COLUMN11            "Grupo"
-       IDS_SHV_COLUMN12            "Filename"
-       IDS_SHV_COLUMN13            "Category"
-       IDS_SHV_COLUMN_DELFROM      "Original location"
-       IDS_SHV_COLUMN_DELDATE      "Date deleted"
-       IDS_SHV_COLUMN_FONTTYPE     "Fonttype"
-       IDS_SHV_COLUMN_WORKGROUP    "Workgroup"
-       IDS_SHV_NETWORKLOCATION     "Network Location"
-       IDS_SHV_COLUMN_DOCUMENTS    "Documents"
-       IDS_SHV_COLUMN_STATUS       "Status"
-       IDS_SHV_COLUMN_COMMENTS     "Comments"
-       IDS_SHV_COLUMN_LOCATION     "Location"
-       IDS_SHV_COLUMN_MODEL        "Model"
+       IDS_SHV_COLUMN12            "Nome do ficheiro"
+       IDS_SHV_COLUMN13            "Categoria"
+       IDS_SHV_COLUMN_DELFROM      "Localização original"
+       IDS_SHV_COLUMN_DELDATE      "Data da eliminação"
+       IDS_SHV_COLUMN_FONTTYPE     "Tipo de letra"
+       IDS_SHV_COLUMN_WORKGROUP    "Grupo de trabalho"
+       IDS_SHV_NETWORKLOCATION     "localizações na rede"
+       IDS_SHV_COLUMN_DOCUMENTS    "Documentos"
+       IDS_SHV_COLUMN_STATUS       "Estado"
+       IDS_SHV_COLUMN_COMMENTS     "Commentários"
+       IDS_SHV_COLUMN_LOCATION     "Localização"
+       IDS_SHV_COLUMN_MODEL        "Modelo"
 
        /* special folders */
        IDS_DESKTOP                 "Ambiente de trabalho"
        IDS_MYCOMPUTER              "O Meu Computador"
-       IDS_RECYCLEBIN_FOLDER_NAME  "Trash"
-       IDS_CONTROLPANEL            "Control Panel"
-       IDS_ADMINISTRATIVETOOLS     "Administrative Tools"
+       IDS_RECYCLEBIN_FOLDER_NAME  "Reciclagem"
+       IDS_CONTROLPANEL            "Painel de Controlo"
+       IDS_ADMINISTRATIVETOOLS     "Ferramentas Administrativas"
 
        /* context menus */
        IDS_VIEW_LARGE              "Ícones &grandes"
@@ -634,15 +635,15 @@ BEGIN
        IDS_VIEW_DETAILS            "&Detalhes"
        IDS_SELECT                  "Seleccionar"
        IDS_OPEN                    "Abrir"
-       IDS_CREATELINK              "Create &Link"
-       IDS_COPY                    "Copy"
-       IDS_DELETE                  "Delete"
-       IDS_PROPERTIES              "Properties"
-       IDS_CUT                     "Cut"
-       IDS_RESTORE                 "Restore"
-       IDS_FORMATDRIVE             "Format..."
-       IDS_RENAME                  "Rename"
-       IDS_INSERT                  "Insert"
+       IDS_CREATELINK              "Criar &Atalho"
+       IDS_COPY                    "Copiar"
+       IDS_DELETE                  "Apagar"
+       IDS_PROPERTIES              "Propriedades"
+       IDS_CUT                     "Cortar"
+       IDS_RESTORE                 "Restaurar"
+       IDS_FORMATDRIVE             "Formatar..."
+       IDS_RENAME                  "Renaomear"
+       IDS_INSERT                  "Inserir"
 
        IDS_CREATEFOLDER_DENIED     "Não é possível criar nova pasta: Permissão negada."
        IDS_CREATEFOLDER_CAPTION    "Erro durante a criação da nova pasta"
@@ -650,23 +651,25 @@ BEGIN
        IDS_DELETEFOLDER_CAPTION    "Confirmar exclusão da pasta"
        IDS_DELETEITEM_TEXT         "Tem certeza que deseja excluir '%1'?"
        IDS_DELETEMULTIPLE_TEXT     "Tem certeza que deseja excluir estes %1 itens?"
-       IDS_DELETESELECTED_TEXT     "Are you sure you want to delete the selected item(s)?"
-       IDS_TRASHITEM_TEXT          "Are you sure that you want to send '%1' to the Trash?"
-       IDS_TRASHFOLDER_TEXT        "Are you sure that you want to send '%1' and all its content to the Trash?"
-       IDS_TRASHMULTIPLE_TEXT      "Are you sure that you want to send these %1 items to the Trash?"
-       IDS_CANTTRASH_TEXT          "The item '%1' can't be sent to Trash. Do you want to delete it instead?"
-       IDS_OVERWRITEFILE_TEXT      "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
+       IDS_DELETESELECTED_TEXT     "Tem a certeza que quer eliminar os item(s) seleccionado(s)?"
+       IDS_TRASHITEM_TEXT          "Tem a certeza que quer enviar '%1' para a reciclagem?"
+       IDS_TRASHFOLDER_TEXT        "Tem a certeza que quer enviar '%1' e todo o seu conteúdo para a reciclagem?"
+       IDS_TRASHMULTIPLE_TEXT      "Tem a certeza que quer enviar este '%1' item para a reciclagem?"
+       IDS_CANTTRASH_TEXT          "O item '%1' não pode ser enviado para a reciclagem. Em vez disso pretende eliminá-lo?"
+       IDS_OVERWRITEFILE_TEXT      "Esta pasta já contém um ficheiro com o nome '%1'.\n\npretende substituí-lo?"
        IDS_OVERWRITEFILE_CAPTION   "Confirmar substituição de ficheiro"
-       IDS_OVERWRITEFOLDER_TEXT    "This folder already contains a folder named '%1'.\n\n"\
-               "If the files in the destination folder have the same names as files in the\n"\
-               "selected folder they will be replaced. Do you still want to move or copy\n"\
-               "the folder?"
+       IDS_OVERWRITEFOLDER_TEXT    "Esta pasta já contém uma pasta com o nome '%1'.\n\n"\
+               "Se os ficheiros na pasta de destino tiverem o mesmo nome dos ficheiros na\n"\
+               "pasta seleccionada, serão substituídos. Ainda assim pretende mover ou copiar\n"\
+               "a pasta?"
 
        /* message box strings */
        IDS_RESTART_TITLE           "Reiniciar"
        IDS_RESTART_PROMPT          "Deseja simular a reinicialização do Windows?"
        IDS_SHUTDOWN_TITLE          "Desligar"
-       IDS_SHUTDOWN_PROMPT         "Deseja finalizar esta sessão do Wine?"
+       IDS_SHUTDOWN_PROMPT         "Deseja finalizar esta sessão do ReactOS?"
+       IDS_LOGOFF_TITLE            "Terminar a sessão"
+       IDS_LOGOFF_PROMPT           "Pretende terminar a sessão?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Menu Iniciar\\Programas"
@@ -679,12 +682,12 @@ BEGIN
        IDS_MYMUSIC                 "As Minhas Músicas"
        IDS_MYVIDEO                 "Os Meus Vídeos"
        IDS_DESKTOPDIRECTORY        "Ambiente de Trabalho"
-       IDS_NETHOOD                 "NetHood"
+       IDS_NETHOOD                 "Visinhança na rede"
        IDS_TEMPLATES               "Modelos"
-       IDS_APPDATA                 "Application Data"
+       IDS_APPDATA                 "Dados de Aplicação"
        IDS_PRINTHOOD               "PrintHood"
-       IDS_LOCAL_APPDATA           "Definições locais\\Application Data"
-       IDS_INTERNET_CACHE          "Definições locais\\Temporary Internet Files"
+       IDS_LOCAL_APPDATA           "Definições locais\\Dados de Aplicação"
+       IDS_INTERNET_CACHE          "Definições locais\\Ficheiros Temporários da Internet"
        IDS_COOKIES                 "Cookies"
        IDS_HISTORY                 "Definições locais\\Histórico"
        IDS_PROGRAM_FILES           "Programas"
@@ -695,60 +698,62 @@ BEGIN
        IDS_COMMON_MUSIC            "Os Meus Documentos\\As Minhas Músicas"
        IDS_COMMON_PICTURES         "Os Meus Documentos\\As Minhas Imagens"
        IDS_COMMON_VIDEO            "Os Meus Documentos\\Os Meus Vídeos"
-       IDS_CDBURN_AREA             "Definições locais\\Application Data\\Microsoft\\CD Burning"
-       IDS_NETWORKPLACE            "My Network Places"
+       IDS_CDBURN_AREA             "Definições locais\\Dados de Aplicação\\Microsoft\\CD Burning"
+       IDS_NETWORKPLACE            "Os Meus Locais da Rede"
 
-       IDS_NEWFOLDER               "New Folder"
+       IDS_NEWFOLDER               "Nova Pasta"
 
-       IDS_DRIVE_FIXED             "Local Disk"
+       IDS_DRIVE_FIXED             "Disco Local"
        IDS_DRIVE_CDROM             "CDROM"
-       IDS_DRIVE_NETWORK           "Network Disk"
+       IDS_DRIVE_NETWORK           "Disco de Rede"
 
-       IDS_OPEN_WITH               "Open With"
-       IDS_OPEN_WITH_CHOOSE        "Choose Program..."
+       IDS_OPEN_WITH               "Abre com..."
+       IDS_OPEN_WITH_CHOOSE        "Escolha Programa..."
 
-       IDS_SHELL_ABOUT_AUTHORS     "&Authors"
-       IDS_SHELL_ABOUT_BACK        "< &Back"
+       IDS_SHELL_ABOUT_AUTHORS     "&Autores"
+       IDS_SHELL_ABOUT_BACK        "< &Trás"
        FCIDM_SHVIEW_NEW            "Novo"
        FCIDM_SHVIEW_NEWFOLDER      "&Pasta"
        FCIDM_SHVIEW_NEWLINK        "&Atalho"
-       IDS_FOLDER_OPTIONS          "Folder Options"
-       IDS_RECYCLEBIN_LOCATION     "Recycle Bin Location"
-       IDS_RECYCLEBIN_DISKSPACE    "Space Available"
-       IDS_EMPTY_BITBUCKET         "Empty Recycle Bin"
-       IDS_PICK_ICON_TITLE         "Choose Icon"
-       IDS_PICK_ICON_FILTER        "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0"
-       IDS_OPEN_WITH_FILTER        "Executable Files\0*.exe\0"
-       IDS_DIRECTORY               "Folder"
-       IDS_VIRTUAL_DRIVER          "Virtual Device Driver"
+       IDS_FOLDER_OPTIONS          "Opções das Pastas"
+       IDS_RECYCLEBIN_LOCATION     "Localização da Reciclagem"
+       IDS_RECYCLEBIN_DISKSPACE    "Espaço Disponível"
+       IDS_EMPTY_BITBUCKET         "Esvaziar Reciclagem"
+       IDS_PICK_ICON_TITLE         "Escolha Ícone"
+       IDS_PICK_ICON_FILTER        "Ficheiros de Ícones(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0"
+       IDS_OPEN_WITH_FILTER        "Ficheiros Executáveis\0*.exe\0"
+       IDS_DIRECTORY               "Pasta"
+       IDS_VIRTUAL_DRIVER          "Driver de Dispositivo Virtual"
        IDS_BAT_FILE                "ReactOS Batch File"
        IDS_CMD_FILE                "ReactOS Command Script"
-       IDS_COM_FILE                "Dos Application"
-       IDS_CPL_FILE                "Control Panel Item"
+       IDS_COM_FILE                "Aplicação Dos"
+       IDS_CPL_FILE                "Item do Painel de Controle"
        IDS_CUR_FILE                "Cursor"
-       IDS_DLL_FILE                "Application Extension"
-       IDS_DRV_FILE                "Device Driver"
-       IDS_EXE_FILE                "Application"
-       IDS_FON_FILE                "Font file"
-       IDS_TTF_FILE                "TrueType Font file"
-       IDS_HLP_FILE                "Help File"
-       IDS_INI_FILE                "Configuration Settings"
-       IDS_LNK_FILE                "Shortcut"
-       IDS_SYS_FILE                "System file"
-
-       IDS_OPEN_VERB               "Open"
-       IDS_RUNAS_VERB              "Run as "
-       IDS_EDIT_VERB               "Edit"
-       IDS_FIND_VERB               "Find"
-       IDS_PRINT_VERB              "Print"
-       IDS_PLAY_VERB               "Play"
-       IDS_PREVIEW_VERB            "Preview"
-
-       IDS_FILE_FOLDER             "%u Files, %u Folders"
-       IDS_PRINTERS                "Printers"
-       IDS_FONTS                   "Fonts"
-       IDS_INSTALLNEWFONT          "Install New Font..."
-
-       IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
-       IDS_COPY_OF                 "Copy of"
+       IDS_DLL_FILE                "Extensão da Aplicação"
+       IDS_DRV_FILE                "Driver do Dispositivo"
+       IDS_EXE_FILE                "Aplicação"
+       IDS_FON_FILE                "Ficheiro de tipo de letra"
+       IDS_TTF_FILE                "Tipo de letra TrueType"
+       IDS_HLP_FILE                "Ficheiro de Ajuda"
+       IDS_INI_FILE                "Definições"
+       IDS_LNK_FILE                "Atalho"
+       IDS_SYS_FILE                "Ficheiro de Sistema"
+
+       IDS_OPEN_VERB               "Abrir"
+       IDS_RUNAS_VERB              "Executar como "
+       IDS_EDIT_VERB               "Editar"
+       IDS_FIND_VERB               "Procurar"
+       IDS_PRINT_VERB              "Imprimir"
+       IDS_PLAY_VERB               "Reproduzir"
+       IDS_PREVIEW_VERB            "Previzualizar"
+
+       IDS_FILE_FOLDER             "%u Ficheiros, %u Pastas"
+       IDS_PRINTERS                "Impressoras"
+       IDS_FONTS                   "Tipos de Letras"
+       IDS_INSTALLNEWFONT          "Instalar novo tipo de letra..."
+
+       IDS_DEFAULT_CLUSTER_SIZE    "Tamanho da unidade de atribuição"
+       IDS_COPY_OF                 "Cópia de"
+
+       IDS_SHLEXEC_NOASSOC         "Não existe um programa Windows configurado para abrir este tipo de ficheiro."
 END
index 656bc41..fb24c2b 100644 (file)
@@ -361,7 +361,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -668,6 +668,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Vreți să reporniți sistemul?"
        IDS_SHUTDOWN_TITLE          "Închidere"
        IDS_SHUTDOWN_PROMPT         "Vreți să închideți computerul?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Meniu Start\\Programe"
@@ -751,6 +753,8 @@ BEGIN
        IDS_INSTALLNEWFONT          "Instalare font nou..."
 
        IDS_DEFAULT_CLUSTER_SIZE    "Mărime de alocare implicită"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
 
 #pragma code_page(default)
index 7d6e1e1..daf4f2c 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Âûáîð ïðîãðàììû"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -664,6 +664,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Âû äåéñòâèòåëüíî õîòèòå ïåðåçàãðóçèòü ReactOS?"
        IDS_SHUTDOWN_TITLE          "Âûêëþ÷èòü ïèòàíèå"
        IDS_SHUTDOWN_PROMPT         "Çàêîí÷èòü ðàáîòó ñ ReactOS?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Ãëàâíîå ìåíþ\\Ïðîãðàììû"
@@ -748,4 +750,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Âûäåëÿåìûé ïî óìîë÷àíèþ ðàçìåð"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 2ec58ec..897564b 100644 (file)
@@ -364,7 +364,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Otvori\9d v programe"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -671,6 +671,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Naozaj chcete re\9atartova\9d systém?"
        IDS_SHUTDOWN_TITLE          "Vypnú\9d"
        IDS_SHUTDOWN_PROMPT         "Naozaj chcete vypnú\9d poèítaè?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Ponuka \8atart\\Programy"
@@ -755,4 +757,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Predvolená alokaèná ve¾kos\9d" //Default allocation size
        IDS_COPY_OF                 "Kópia" //Copy of
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 876be4b..9789ec3 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -665,6 +665,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Do you want to restart the system?"
        IDS_SHUTDOWN_TITLE          "Shutdown"
        IDS_SHUTDOWN_PROMPT         "Do you want to shutdown?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -749,4 +751,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "Noben Okenski program ni nastavljen, da bi odpiral ta tip datotek."
 END
index e7a520f..4ddd5c3 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -665,6 +665,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Do you want to restart the system?"
        IDS_SHUTDOWN_TITLE          "Shutdown"
        IDS_SHUTDOWN_PROMPT         "Do you want to shutdown?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -749,4 +751,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 49a154c..633936f 100644 (file)
@@ -358,7 +358,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -665,6 +665,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Do you want to restart the system?"
        IDS_SHUTDOWN_TITLE          "Oturumu Kapat"
        IDS_SHUTDOWN_PROMPT         "Do you want to shutdown?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programlar"
@@ -749,4 +751,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 3846965..807a7c9 100644 (file)
@@ -359,7 +359,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Âèá³ð ïðîãðàìè"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -666,6 +666,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Âè õî÷åòå ïåðåçàâàíòàæèòè ñèñòåìó?"
        IDS_SHUTDOWN_TITLE          "Âèìêíóòè"
        IDS_SHUTDOWN_PROMPT         "Âè õî÷åòå âèìêíóòè êîìï'þòåð?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -750,4 +752,6 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Ðîçì³ð êëàñòåðà çà ïðîìîâ÷àííÿì"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
index 5180db5..aa54e3e 100644 (file)
@@ -347,7 +347,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -654,6 +654,8 @@ BEGIN
        IDS_RESTART_PROMPT          "ÊÇ·ñÖØÐÂÆô¶¯ÏµÍ³?"
        IDS_SHUTDOWN_TITLE          "¹Ø»ú"
        IDS_SHUTDOWN_PROMPT         "ÊÇ·ñ¹Ø±Õϵͳ?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -737,5 +739,7 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
 
index fc76bf1..fcf7abf 100644 (file)
@@ -359,7 +359,7 @@ BEGIN
 END
 
 OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256
-STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION
+STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION
 CAPTION "Open With"
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
@@ -666,6 +666,8 @@ BEGIN
        IDS_RESTART_PROMPT          "Do you want to restart the system?"
        IDS_SHUTDOWN_TITLE          "Shutdown"
        IDS_SHUTDOWN_PROMPT         "Do you want to shutdown?"
+       IDS_LOGOFF_TITLE            "Log Off"
+       IDS_LOGOFF_PROMPT           "Do you want to log off?"
 
        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
@@ -750,6 +752,8 @@ BEGIN
 
        IDS_DEFAULT_CLUSTER_SIZE    "Default allocation size"
        IDS_COPY_OF                 "Copy of"
+
+       IDS_SHLEXEC_NOASSOC         "There is no Windows program configured to open this type of file."
 END
 
 #pragma code_page(default)
index dc66376..1b6adec 100644 (file)
@@ -719,12 +719,12 @@ static INT_PTR CALLBACK OpenWithProgrammDlg(HWND hwndDlg, UINT uMsg, WPARAM wPar
 
                  if (lpdis->itemID == index)
                  {
-                     /* paint focused item with blue background */
+                     /* paint focused item with standard background colour */
                      HBRUSH hBrush;
-                     hBrush = CreateSolidBrush(RGB(0, 0, 255));
+                     hBrush = CreateSolidBrush(RGB(46, 104, 160));
                      FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
                      DeleteObject(hBrush);
-                     preBkColor = SetBkColor(lpdis->hDC, RGB(255, 255, 255));
+                     preBkColor = SetBkColor(lpdis->hDC, RGB(46, 104, 160));
                  }
                  else
                  {
@@ -756,6 +756,10 @@ static INT_PTR CALLBACK OpenWithProgrammDlg(HWND hwndDlg, UINT uMsg, WPARAM wPar
                  break;
          }
          break;
+    case WM_CLOSE:
+        FreeListItems(hwndDlg);
+        EndDialog(hwndDlg, 0);
+        return TRUE;
     default:
         break;
     }
index 57e3701..a7b9251 100644 (file)
@@ -1017,8 +1017,8 @@ ExecuteAppletFromCLSID(LPOLESTR pOleStr)
     dwSize = sizeof(szCmd);
     if (RegGetValueW(HKEY_CLASSES_ROOT, szBuffer, NULL, RRF_RT_REG_SZ, &dwType, (PVOID)szCmd, &dwSize) != ERROR_SUCCESS)
     {
-        ERR("RegGetValueW failed with %u\n", GetLastError());
-        return E_FAIL;
+        wcscpy(szCmd, L"%SystemRoot%\\Explorer.exe ::");
+        wcscat(szCmd, pOleStr);
     }
 
 #if 0
@@ -1298,8 +1298,8 @@ static HRESULT WINAPI ICPanel_IContextMenu2_InvokeCommand(
        sei.hwnd = lpcmi->hwnd;
        sei.nShow = SW_SHOWNORMAL;
        sei.lpVerb = L"open";
-       ShellExecuteExW(&sei);
-       if (sei.hInstApp <= (HINSTANCE)32)
+
+       if (ShellExecuteExW(&sei) == FALSE)
           return E_FAIL;
     }
     else if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_CREATELINK)) //FIXME
index d4f87b6..4ec244f 100644 (file)
@@ -979,8 +979,7 @@ static HRESULT WINAPI ISF_Fonts_IContextMenu2_InvokeCommand(
         pfont = _ILGetFontStruct(This->apidl);
         sei.lpFile = pfont->szName + pfont->offsFile;
 
-        ShellExecuteExW(&sei);
-        if (sei.hInstApp <= (HINSTANCE)32)
+        if (ShellExecuteExW(&sei) == FALSE)
            return E_FAIL;
     }
     else if (lpcmi->lpVerb == MAKEINTRESOURCEA(4))
index 6992d18..defe95f 100644 (file)
@@ -33,6 +33,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
 #define IsDotDir(x)     ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
 
 #define FO_MASK         0xF
+#define WM_FILE       (WM_USER + 1)
+#define TIMER_ID      (100)
 
 static const WCHAR wWildcardFile[] = {'*',0};
 static const WCHAR wWildcardChars[] = {'*','?',0};
@@ -52,6 +54,40 @@ typedef struct
     BOOL bCancelled;
 } FILE_OPERATION;
 
+#define ERROR_SHELL_INTERNAL_FILE_NOT_FOUND 1026
+
+typedef struct
+{
+    DWORD attributes;
+    LPWSTR szDirectory;
+    LPWSTR szFilename;
+    LPWSTR szFullPath;
+    BOOL bFromWildcard;
+    BOOL bFromRelative;
+    BOOL bExists;
+} FILE_ENTRY;
+
+typedef struct
+{
+    FILE_ENTRY *feFiles;
+    DWORD num_alloc;
+    DWORD dwNumFiles;
+    BOOL bAnyFromWildcard;
+    BOOL bAnyDirectories;
+    BOOL bAnyDontExist;
+} FILE_LIST;
+
+typedef struct
+{
+    FILE_LIST * from;
+    FILE_LIST * to;
+    FILE_OPERATION * op;
+    DWORD Index;
+    HWND hDlgCtrl;
+    HWND hwndDlg;
+}FILE_OPERATION_CONTEXT;
+
+
 /* Confirm dialogs with an optional "Yes To All" as used in file operations confirmations
  */
 static const WCHAR CONFIRM_MSG_PROP[] = {'W','I','N','E','_','C','O','N','F','I','R','M',0};
@@ -514,6 +550,163 @@ static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest)
        return GetLastError();
 }
 
+static WINAPI DWORD SHOperationProgressRoutine(LARGE_INTEGER TotalFileSize, LARGE_INTEGER TotalBytesTransferred, LARGE_INTEGER StreamSize, LARGE_INTEGER StreamBytesTransferred, DWORD dwStreamNumber, DWORD dwCallbackReason, HANDLE hSourceFile, HANDLE hDestinationFile, LPVOID lpData)
+{
+    FILE_OPERATION_CONTEXT * Context;
+    LARGE_INTEGER Progress;
+
+    /* get context */
+    Context = (FILE_OPERATION_CONTEXT*)lpData;
+
+    if (TotalBytesTransferred.QuadPart)
+    {
+        Progress.QuadPart = (TotalBytesTransferred.QuadPart * 100) / TotalFileSize.QuadPart;
+    }
+    else
+    {
+        Progress.QuadPart = 1;
+    }
+
+    /* update progress bar */
+    SendMessageW(Context->hDlgCtrl, PBM_SETPOS, (WPARAM)Progress.u.LowPart, 0);
+
+    if (TotalBytesTransferred.QuadPart == TotalFileSize.QuadPart)
+    {
+        /* file was copied */
+        Context->Index++;
+        PostMessageW(Context->hwndDlg, WM_FILE, 0, 0);
+    }
+
+    return PROGRESS_CONTINUE;
+}
+
+BOOL
+QueueFile(
+    FILE_OPERATION_CONTEXT * Context)
+{
+    FILE_ENTRY * from, *to;
+    BOOL bRet = FALSE;
+
+    if (Context->Index >= Context->from->dwNumFiles)
+        return FALSE;
+
+    /* get current file */
+    from = &Context->from->feFiles[Context->Index];
+
+    if (Context->op->req->fFlags != FO_DELETE)
+        to = &Context->to->feFiles[Context->Index];
+
+    /* update status */
+    SendDlgItemMessageW(Context->hwndDlg, 14001, WM_SETTEXT, 0, (LPARAM)from->szFullPath);
+
+    if (Context->op->req->wFunc == FO_COPY)
+    {
+        bRet = CopyFileExW(from->szFullPath, to->szFullPath, SHOperationProgressRoutine, (LPVOID)Context, &Context->op->bCancelled, 0);
+    }
+    else if (Context->op->req->wFunc == FO_MOVE)
+    {
+        //bRet = MoveFileWithProgressW(from->szFullPath, to->szFullPath, SHOperationProgressRoutine, (LPVOID)Context, MOVEFILE_COPY_ALLOWED);
+    }
+    else if (Context->op->req->wFunc == FO_DELETE)
+    {
+        bRet = DeleteFile(from->szFullPath);
+    }
+
+    return bRet;
+}
+
+static INT_PTR CALLBACK SHOperationDialog(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    FILE_OPERATION_CONTEXT * Context;
+
+    Context = (FILE_OPERATION_CONTEXT*) GetWindowLongPtr(hwndDlg, DWLP_USER);
+
+    switch(uMsg)
+    {
+    case WM_INITDIALOG:
+        SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)lParam);
+
+        /* get context */
+        Context = (FILE_OPERATION_CONTEXT*)lParam;
+
+        /* store progress bar handle */
+        Context->hDlgCtrl = GetDlgItem(hwndDlg, 14000);
+
+        /* store window handle */
+        Context->hwndDlg = hwndDlg;
+
+        /* set progress bar range */
+        (void)SendMessageW(Context->hDlgCtrl, (UINT) PBM_SETRANGE, 0, MAKELPARAM(0, 100));
+
+        /* start file queueing */
+        SetTimer(hwndDlg, TIMER_ID, 1000, NULL);
+        //QueueFile(Context);
+
+        return TRUE;
+
+    case WM_CLOSE:
+        Context->op->bCancelled = TRUE;
+        EndDialog(hwndDlg, Context->op->bCancelled);
+        return TRUE;
+    case WM_COMMAND:
+        if (LOWORD(wParam) == 14002)
+        {
+            Context->op->bCancelled = TRUE;
+            EndDialog(hwndDlg, Context->op->bCancelled);
+            return TRUE;
+        }
+        break;
+    case WM_TIMER:
+        if (wParam == TIMER_ID)
+        {
+            QueueFile(Context);
+            KillTimer(hwndDlg, TIMER_ID);
+        }
+        break;
+    case WM_FILE:
+        if (!QueueFile(Context))
+            EndDialog(hwndDlg, Context->op->bCancelled);
+    default:
+        break;
+    }
+    return FALSE;
+}
+
+HRESULT
+SHShowFileOperationDialog(FILE_OPERATION *op, FILE_LIST *flFrom, FILE_LIST *flTo)
+{
+    HWND hwnd;
+    BOOL bRet;
+    MSG msg;
+    FILE_OPERATION_CONTEXT Context;
+
+    Context.from = flFrom;
+    Context.to = flTo;
+    Context.op = op;
+    Context.Index = 0;
+    Context.op->bCancelled = FALSE;
+
+    hwnd = CreateDialogParam(shell32_hInstance, MAKEINTRESOURCE(IDD_SH_FILE_COPY), NULL, SHOperationDialog, (LPARAM)&Context);
+    if (hwnd == NULL)
+    {
+        ERR("Failed to create dialog\n");
+        return E_FAIL;
+    }
+    ShowWindow(hwnd, SW_SHOWNORMAL);
+
+    while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) 
+    { 
+        if (!IsWindow(hwnd) || !IsDialogMessage(hwnd, &msg)) 
+        {
+            TranslateMessage(&msg); 
+            DispatchMessage(&msg); 
+        }
+    }
+
+    return NOERROR;
+}
+
+
 /************************************************************************
  * SHNotifyCopyFile          [internal]
  *
@@ -808,28 +1001,7 @@ int WINAPI SHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp)
        return retCode;
 }
 
-#define ERROR_SHELL_INTERNAL_FILE_NOT_FOUND 1026
 
-typedef struct
-{
-    DWORD attributes;
-    LPWSTR szDirectory;
-    LPWSTR szFilename;
-    LPWSTR szFullPath;
-    BOOL bFromWildcard;
-    BOOL bFromRelative;
-    BOOL bExists;
-} FILE_ENTRY;
-
-typedef struct
-{
-    FILE_ENTRY *feFiles;
-    DWORD num_alloc;
-    DWORD dwNumFiles;
-    BOOL bAnyFromWildcard;
-    BOOL bAnyDirectories;
-    BOOL bAnyDontExist;
-} FILE_LIST;
 
 
 static void __inline grow_list(FILE_LIST *list)
index e28efb0..43e409c 100644 (file)
@@ -90,6 +90,9 @@
 #define IDS_FONTS                   76
 #define IDS_PRINTERS                77
 
+#define IDS_LOGOFF_TITLE            78
+#define IDS_LOGOFF_PROMPT           79
+
 #define IDS_CREATEFOLDER_DENIED     128
 #define IDS_CREATEFOLDER_CAPTION    129
 #define IDS_DELETEITEM_CAPTION      130
 #define IDS_SYS_FILE                171
 #define IDS_EMPTY_BITBUCKET         172
 #define IDS_SHLEXEC_NOASSOC         173
+#define IDS_FILE_TYPES              174
+#define IDS_FILE_DETAILS            175
 
 #define IDS_OPEN_VERB               300
 #define IDS_RUNAS_VERB              301
 #define IDD_TREEVIEW                0x3741
 #define SHELL_EXTENDED_SHORTCUT_DLG 0x4000
 #define OPEN_WITH_PROGRAMM_DLG      0x4001
+#define IDD_SH_FILE_COPY            0x4002
 
 /* ID's of the ShellAbout controls */
 // Part 1 - ID's identical to Windows Server 2003 SP1's shell32.dll
index 71c25a7..08c9c3c 100644 (file)
@@ -48,7 +48,7 @@ static LPIDefaultContextMenuImpl __inline impl_from_IContextMenu( IContextMenu2
 }
 
 VOID INewItem_SetCurrentShellFolder(IShellFolder * psfParent); // HACK
-
+WCHAR *build_paths_list(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls);
 
 static
 HRESULT
@@ -1297,12 +1297,12 @@ DoDelete(
     HRESULT hr;
     STRRET strTemp;
     WCHAR szPath[MAX_PATH];
+    LPWSTR wszPath, wszPos;
     SHFILEOPSTRUCTW op;
     int ret;
     LPSHELLBROWSER lpSB;
     HWND hwnd;
 
-
     hr = IShellFolder2_GetDisplayNameOf(This->dcm.psf, This->dcm.apidl[0], SHGDN_FORPARSING, &strTemp);
     if(hr != S_OK)
     {
@@ -1316,20 +1316,26 @@ DoDelete(
         ERR("StrRetToBufW failed with %x\n", hr);
         return hr;
     }
-    /* FIXME
-     * implement deletion with multiple files
-     */
+
+    /* Only keep the base path */
+    wszPos = strrchrW(szPath, '\\');
+    if (wszPos != NULL)
+    {
+        *(wszPos + 1) = '\0';
+    }
+
+    wszPath = build_paths_list(szPath, This->dcm.cidl, This->dcm.apidl);
 
     ZeroMemory(&op, sizeof(op));
     op.hwnd = GetActiveWindow();
     op.wFunc = FO_DELETE;
-    op.pFrom = szPath;
+    op.pFrom = wszPath;
     op.fFlags = FOF_ALLOWUNDO;
     ret = SHFileOperationW(&op);
 
     if (ret)
     {
-        TRACE("SHFileOperation failed with %0x%x", GetLastError());
+        ERR("SHFileOperation failed with 0x%x for %s\n", GetLastError(), debugstr_w(wszPath));
         return S_OK;
     }
 
@@ -1348,6 +1354,7 @@ DoDelete(
     }
     NotifyShellViewWindow(lpcmi, TRUE);
 
+    HeapFree(GetProcessHeap(), 0, wszPath);
     return S_OK;
 
 }
index 364bbfe..332bdb6 100644 (file)
@@ -42,6 +42,7 @@
 #include "mmsystem.h"
 #include "objbase.h"
 #include "exdisp.h"
+#include "shdeprecated.h"
 #include "shlobj.h"
 #include "shlwapi.h"
 #include "shellapi.h"
@@ -309,24 +310,22 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
   BSTR property;
   IEnumFORMATETC* pIEnumFormatEtc = NULL;
   VARIANTARG var;
-  HRESULT hRet;
-  IWebBrowserApp* pBrowser = NULL;
+  HRESULT hr;
+  IWebBrowserApp* pBrowser;
 
   TRACE("(%p, %p)\n", lpBC, lpUnknown);
 
-  /* Get An IWebBrowserApp interface from  lpUnknown */
-  hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
-  if (FAILED(hRet) || !pBrowser)
-    return E_NOINTERFACE;
+  hr = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (void**)&pBrowser);
+  if (FAILED(hr))
+    return hr;
 
   V_VT(&var) = VT_EMPTY;
 
   /* The property we get is the browsers clipboard enumerator */
   property = SysAllocString(szProperty);
-  hRet = IWebBrowserApp_GetProperty(pBrowser, property, &var);
+  hr = IWebBrowserApp_GetProperty(pBrowser, property, &var);
   SysFreeString(property);
-  if (FAILED(hRet))
-    return hRet;
+  if (FAILED(hr)) goto exit;
 
   if (V_VT(&var) == VT_EMPTY)
   {
@@ -340,7 +339,10 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
 
     if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
                      "Version\\Internet Settings\\Accepted Documents", &hDocs))
-      return E_FAIL;
+    {
+      hr = E_FAIL;
+      goto exit;
+    }
 
     /* Get count of values in key */
     while (!dwRet)
@@ -355,7 +357,11 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
     /* Note: dwCount = number of items + 1; The extra item is the end node */
     format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
     if (!formatList)
-      return E_OUTOFMEMORY;
+    {
+      RegCloseKey(hDocs);
+      hr = E_OUTOFMEMORY;
+      goto exit;
+    }
 
     if (dwNumValues > 1)
     {
@@ -372,7 +378,12 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
         dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
                               (PBYTE)szValueBuff, &dwValueSize);
         if (!dwRet)
-          return E_FAIL;
+        {
+          HeapFree(GetProcessHeap(), 0, formatList);
+          RegCloseKey(hDocs);
+          hr = E_FAIL;
+          goto exit;
+        }
 
         format->cfFormat = RegisterClipboardFormatA(szValueBuff);
         format->ptd = NULL;
@@ -385,6 +396,8 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
       }
     }
 
+    RegCloseKey(hDocs);
+
     /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
     format->cfFormat = 0;
     format->ptd = NULL;
@@ -393,22 +406,21 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
     format->tymed = -1;
 
     /* Create a clipboard enumerator */
-    hRet = CreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
-
-    if (FAILED(hRet) || !pIEnumFormatEtc)
-      return hRet;
+    hr = CreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
+    HeapFree(GetProcessHeap(), 0, formatList);
+    if (FAILED(hr)) goto exit;
 
     /* Set our enumerator as the browsers property */
     V_VT(&var) = VT_UNKNOWN;
     V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
 
     property = SysAllocString(szProperty);
-    hRet = IWebBrowserApp_PutProperty(pBrowser, property, var);
+    hr = IWebBrowserApp_PutProperty(pBrowser, property, var);
     SysFreeString(property);
-    if (FAILED(hRet))
+    if (FAILED(hr))
     {
        IEnumFORMATETC_Release(pIEnumFormatEtc);
-       goto RegisterDefaultAcceptHeaders_Exit;
+       goto exit;
     }
   }
 
@@ -422,28 +434,26 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
 
     /* Get an IEnumFormatEtc interface from the variants value */
     pIEnumFormatEtc = NULL;
-    hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
-                                   (PVOID)&pIEnumFormatEtc);
-    if (hRet == S_OK && pIEnumFormatEtc)
+    hr = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC, (void**)&pIEnumFormatEtc);
+    if (hr == S_OK && pIEnumFormatEtc)
     {
       /* Clone and register the enumerator */
-      hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
-      if (hRet == S_OK && pClone)
+      hr = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
+      if (hr == S_OK && pClone)
       {
         RegisterFormatEnumerator(lpBC, pClone, 0);
 
         IEnumFORMATETC_Release(pClone);
       }
 
-      /* Release the IEnumFormatEtc interface */
       IEnumFORMATETC_Release(pIUnknown);
     }
     IUnknown_Release(V_UNKNOWN(&var));
   }
 
-RegisterDefaultAcceptHeaders_Exit:
+exit:
   IWebBrowserApp_Release(pBrowser);
-  return hRet;
+  return hr;
 }
 
 /*************************************************************************
@@ -500,7 +510,7 @@ HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
         return S_OK;
     }
 
-    /* Did not find a value in the registry or the user buffer is to small */
+    /* Did not find a value in the registry or the user buffer is too small */
     mylcid = GetUserDefaultLCID();
     retval = LcidToRfc1766W(mylcid, mystr, mystrlen);
     len = lstrlenW(mystr);
@@ -1201,7 +1211,7 @@ HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL f
 /*************************************************************************
  *     @       [SHLWAPI.169]
  *
- * Release an interface.
+ * Release an interface and zero a supplied pointer.
  *
  * PARAMS
  *  lpUnknown [I] Object to release
@@ -1209,19 +1219,16 @@ HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL f
  * RETURNS
  *  Nothing.
  */
-DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
+void WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
 {
-    IUnknown *temp;
-
-    TRACE("(%p)\n",lpUnknown);
+    TRACE("(%p)\n", lpUnknown);
 
-    if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
-    temp = *lpUnknown;
-    *lpUnknown = NULL;
+    if(!lpUnknown || !*lpUnknown) return;
 
     TRACE("doing Release\n");
 
-    return IUnknown_Release(temp);
+    IUnknown_Release(*lpUnknown);
+    *lpUnknown = NULL;
 }
 
 /*************************************************************************
@@ -1258,9 +1265,10 @@ LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
  */
 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
 {
-  LPVOID lpUnknown1, lpUnknown2;
+  IUnknown *lpUnknown1, *lpUnknown2;
+  BOOL ret;
 
-  TRACE("%p %p\n", lpInt1, lpInt2);
+  TRACE("(%p %p)\n", lpInt1, lpInt2);
 
   if (!lpInt1 || !lpInt2)
     return FALSE;
@@ -1268,16 +1276,21 @@ BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
   if (lpInt1 == lpInt2)
     return TRUE;
 
-  if (FAILED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown, &lpUnknown1)))
+  if (IUnknown_QueryInterface(lpInt1, &IID_IUnknown, (void**)&lpUnknown1) != S_OK)
     return FALSE;
 
-  if (FAILED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown, &lpUnknown2)))
+  if (IUnknown_QueryInterface(lpInt2, &IID_IUnknown, (void**)&lpUnknown2) != S_OK)
+  {
+    IUnknown_Release(lpUnknown1);
     return FALSE;
+  }
 
-  if (lpUnknown1 == lpUnknown2)
-    return TRUE;
+  ret = lpUnknown1 == lpUnknown2;
 
-  return FALSE;
+  IUnknown_Release(lpUnknown1);
+  IUnknown_Release(lpUnknown2);
+
+  return ret;
 }
 
 /*************************************************************************
@@ -1337,36 +1350,32 @@ HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
 /*************************************************************************
  *      @      [SHLWAPI.173]
  *
- * Call a method on as as yet unidentified object.
+ * Call a SetOwner method of IShellService from specified object.
  *
  * PARAMS
- *  pUnk [I] Object supporting the unidentified interface,
- *  arg  [I] Argument for the call on the object.
+ *  iface [I] Object that supports IShellService
+ *  pUnk  [I] Argument for the SetOwner call
  *
  * RETURNS
- *  S_OK.
+ *  Corresponding return value from last call or E_FAIL for null input
  */
-HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
+HRESULT WINAPI IUnknown_SetOwner(IUnknown *iface, IUnknown *pUnk)
 {
-  static const GUID guid_173 = {
-    0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
-  };
-  IMalloc *pUnk2;
+  IShellService *service;
+  HRESULT hr;
 
-  TRACE("(%p,%d)\n", pUnk, arg);
+  TRACE("(%p, %p)\n", iface, pUnk);
 
-  /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
-   *       We use this interface as its vtable entry is compatible with the
-   *       object in question.
-   * FIXME: Find out what this object is and where it should be defined.
-   */
-  if (pUnk &&
-      SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
+  if (!iface) return E_FAIL;
+
+  hr = IUnknown_QueryInterface(iface, &IID_IShellService, (void**)&service);
+  if (hr == S_OK)
   {
-    IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
-    IMalloc_Release(pUnk2);
+    hr = IShellService_SetOwner(service, pUnk);
+    IShellService_Release(service);
   }
-  return S_OK;
+
+  return hr;
 }
 
 /*************************************************************************
@@ -1473,7 +1482,6 @@ HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID ri
   if (!lpUnknown)
     return E_FAIL;
 
-  /* Get an IServiceProvider interface from the object */
   hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
                                  (LPVOID*)&pService);
 
@@ -1486,12 +1494,92 @@ HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID ri
 
     TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
 
-    /* Release the IServiceProvider interface */
     IUnknown_Release(pService);
   }
   return hRet;
 }
 
+/*************************************************************************
+ *      @      [SHLWAPI.484]
+ *
+ * Calls IOleCommandTarget::Exec() for specified service object.
+ *
+ * PARAMS
+ *  lpUnknown [I] Object to get an IServiceProvider interface from
+ *  service   [I] Service ID for IServiceProvider_QueryService() call
+ *  group     [I] Group ID for IOleCommandTarget::Exec() call
+ *  cmdId     [I] Command ID for IOleCommandTarget::Exec() call
+ *  cmdOpt    [I] Options flags for command
+ *  pIn       [I] Input arguments for command
+ *  pOut      [O] Output arguments for command
+ *
+ * RETURNS
+ *  Success: S_OK. lppOut contains an object providing the requested service
+ *  Failure: An HRESULT error code
+ *
+ * NOTES
+ *  lpUnknown is expected to support the IServiceProvider interface.
+ */
+HRESULT WINAPI IUnknown_QueryServiceExec(IUnknown *lpUnknown, REFIID service,
+    const GUID *group, DWORD cmdId, DWORD cmdOpt, VARIANT *pIn, VARIANT *pOut)
+{
+    IOleCommandTarget *target;
+    HRESULT hr;
+
+    TRACE("%p %s %s %d %08x %p %p\n", lpUnknown, debugstr_guid(service),
+        debugstr_guid(group), cmdId, cmdOpt, pIn, pOut);
+
+    hr = IUnknown_QueryService(lpUnknown, service, &IID_IOleCommandTarget, (void**)&target);
+    if (hr == S_OK)
+    {
+        hr = IOleCommandTarget_Exec(target, group, cmdId, cmdOpt, pIn, pOut);
+        IOleCommandTarget_Release(target);
+    }
+
+    TRACE("<-- hr=0x%08x\n", hr);
+
+    return hr;
+}
+
+/*************************************************************************
+ *      @      [SHLWAPI.514]
+ *
+ * Calls IProfferService methods to proffer/revoke specified service.
+ *
+ * PARAMS
+ *  lpUnknown [I]  Object to get an IServiceProvider interface from
+ *  service   [I]  Service ID for IProfferService::Proffer/Revoke calls
+ *  pService  [I]  Service to proffer. If NULL ::Revoke is called
+ *  pCookie   [IO] Group ID for IOleCommandTarget::Exec() call
+ *
+ * RETURNS
+ *  Success: S_OK. IProffer method returns S_OK
+ *  Failure: An HRESULT error code
+ *
+ * NOTES
+ *  lpUnknown is expected to support the IServiceProvider interface.
+ */
+HRESULT WINAPI IUnknown_ProfferService(IUnknown *lpUnknown, REFGUID service, IServiceProvider *pService, DWORD *pCookie)
+{
+    IProfferService *proffer;
+    HRESULT hr;
+
+    TRACE("%p %s %p %p\n", lpUnknown, debugstr_guid(service), pService, pCookie);
+
+    hr = IUnknown_QueryService(lpUnknown, &IID_IProfferService, &IID_IProfferService, (void**)&proffer);
+    if (hr == S_OK)
+    {
+        if (pService)
+            hr = IProfferService_ProfferService(proffer, service, pService, pCookie);
+        else
+            hr = IProfferService_RevokeService(proffer, *pCookie);
+
+        IProfferService_Release(proffer);
+    }
+
+    return hr;
+}
+
 /*************************************************************************
  *      @      [SHLWAPI.479]
  *
@@ -1546,6 +1634,8 @@ BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
 {
   HMENU hMenu;
 
+  TRACE("%p %s\n", hInst, debugstr_w(szName));
+
   if ((hMenu = LoadMenuW(hInst, szName)))
   {
     if (GetSubMenu(hMenu, 0))
@@ -1629,6 +1719,9 @@ void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lP
 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
 {
   int iItemCount = GetMenuItemCount(hMenu) - 1;
+
+  TRACE("%p\n", hMenu);
+
   while (iItemCount >= 0)
   {
     HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
@@ -1654,6 +1747,7 @@ DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
  */
 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
 {
+  TRACE("%p, %u, %d\n", hMenu, wItemID, bEnable);
   return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
 }
 
@@ -1672,6 +1766,7 @@ UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
  */
 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
 {
+  TRACE("%p, %u, %d\n", hMenu, uID, bCheck);
   return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
 }
 
@@ -1703,6 +1798,8 @@ BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
   DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
   POINTL pt = { 0, 0 };
 
+  TRACE("%p %p 0x%08x %p %p\n", pDrop, pDataObj, grfKeyState, lpPt, pdwEffect);
+
   if (!lpPt)
     lpPt = &pt;
 
@@ -1711,7 +1808,7 @@ BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
 
   IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
 
-  if (*pdwEffect)
+  if (*pdwEffect != DROPEFFECT_NONE)
     return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
 
   IDropTarget_DragLeave(pDrop);
@@ -1803,7 +1900,7 @@ HRESULT WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, BOOL fGotFocus)
   IOleControlSite* lpCSite = NULL;
   HRESULT hRet = E_FAIL;
 
-  TRACE("(%p,%s)\n", lpUnknown, fGotFocus ? "TRUE" : "FALSE");
+  TRACE("(%p, %d)\n", lpUnknown, fGotFocus);
   if (lpUnknown)
   {
     hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
@@ -2061,12 +2158,10 @@ VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
 {
   TRACE("(%p,%p)\n", lppDest, lpUnknown);
 
-  if (lppDest)
-    IUnknown_AtomicRelease(lppDest); /* Release existing interface */
+  IUnknown_AtomicRelease(lppDest);
 
   if (lpUnknown)
   {
-    /* Copy */
     IUnknown_AddRef(lpUnknown);
     *lppDest = lpUnknown;
   }
@@ -2256,12 +2351,6 @@ BOOL WINAPI FDSA_DeleteItem(FDSA_info *info, DWORD where)
     return TRUE;
 }
 
-
-typedef struct {
-    REFIID   refid;
-    DWORD    indx;
-} IFACE_INDEX_TBL;
-
 /*************************************************************************
  *      @      [SHLWAPI.219]
  *
@@ -2272,22 +2361,22 @@ typedef struct {
  *  Failure: E_POINTER or E_NOINTERFACE.
  */
 HRESULT WINAPI QISearch(
-       LPVOID w,           /* [in]   Table of interfaces */
-       IFACE_INDEX_TBL *x, /* [in]   Array of REFIIDs and indexes into the table */
+       void *base,         /* [in]   Table of interfaces */
+       const QITAB *table, /* [in]   Array of REFIIDs and indexes into the table */
        REFIID riid,        /* [in]   REFIID to get interface for */
-       LPVOID *ppv)          /* [out]  Destination for interface pointer */
+       void **ppv)         /* [out]  Destination for interface pointer */
 {
        HRESULT ret;
        IUnknown *a_vtbl;
-       IFACE_INDEX_TBL *xmove;
+       const QITAB *xmove;
 
-       TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
+       TRACE("(%p %p %s %p)\n", base, table, debugstr_guid(riid), ppv);
        if (ppv) {
-           xmove = x;
-           while (xmove->refid) {
-               TRACE("trying (indx %d) %s\n", xmove->indx, debugstr_guid(xmove->refid));
-               if (IsEqualIID(riid, xmove->refid)) {
-                   a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
+           xmove = table;
+           while (xmove->piid) {
+               TRACE("trying (offset %d) %s\n", xmove->dwOffset, debugstr_guid(xmove->piid));
+               if (IsEqualIID(riid, xmove->piid)) {
+                   a_vtbl = (IUnknown*)(xmove->dwOffset + (LPBYTE)base);
                    TRACE("matched, returning (%p)\n", a_vtbl);
                     *ppv = a_vtbl;
                    IUnknown_AddRef(a_vtbl);
@@ -2297,7 +2386,7 @@ HRESULT WINAPI QISearch(
            }
 
            if (IsEqualIID(riid, &IID_IUnknown)) {
-               a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
+               a_vtbl = (IUnknown*)(table->dwOffset + (LPBYTE)base);
                TRACE("returning first for IUnknown (%p)\n", a_vtbl);
                 *ppv = a_vtbl;
                IUnknown_AddRef(a_vtbl);
@@ -2506,27 +2595,27 @@ HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)
  *  dwExStyle  [I] Extra style flags
  *  dwStyle    [I] Style flags
  *  hMenu      [I] Window menu
- *  z          [I] Unknown
+ *  wnd_extra  [I] Window extra bytes value
  *
  * RETURNS
  *  Success: The window handle of the newly created window.
  *  Failure: 0.
  */
 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
-                        DWORD dwStyle, HMENU hMenu, LONG z)
+                                  DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra)
 {
   static const char szClass[] = "WorkerA";
   WNDCLASSA wc;
   HWND hWnd;
 
-  TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
-         wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
+  TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08lx)\n",
+         wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra);
 
   /* Create Window class */
   wc.style         = 0;
   wc.lpfnWndProc   = DefWindowProcA;
   wc.cbClsExtra    = 0;
-  wc.cbWndExtra    = 4;
+  wc.cbWndExtra    = sizeof(LONG_PTR);
   wc.hInstance     = shlwapi_hInstance;
   wc.hIcon         = NULL;
   wc.hCursor       = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
@@ -2534,19 +2623,17 @@ HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle
   wc.lpszMenuName  = NULL;
   wc.lpszClassName = szClass;
 
-  SHRegisterClassA(&wc); /* Register class */
-
-  /* FIXME: Set extra bits in dwExStyle */
+  SHRegisterClassA(&wc);
 
   hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
                          hWndParent, hMenu, shlwapi_hInstance, 0);
   if (hWnd)
   {
-    SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
+    SetWindowLongPtrW(hWnd, 0, wnd_extra);
 
-    if (wndProc)
-      SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
+    if (wndProc) SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
   }
+
   return hWnd;
 }
 
@@ -2729,7 +2816,7 @@ BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
  */
 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
 {
-    return SUCCEEDED(CLSIDFromString((LPOLESTR)idstr, id));
+    return SUCCEEDED(CLSIDFromString((LPCOLESTR)idstr, id));
 }
 
 /*************************************************************************
@@ -2804,18 +2891,21 @@ DWORD WINAPI WhichPlatform(void)
  * Unicode version of SHCreateWorkerWindowA.
  */
 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
-                        DWORD dwStyle, HMENU hMenu, LONG z)
+                        DWORD dwStyle, HMENU hMenu, LONG msg_result)
 {
-  static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
+  static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', 0 };
   WNDCLASSW wc;
   HWND hWnd;
 
-  TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
-         wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
+  TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x)\n",
+         wndProc, hWndParent, dwExStyle, dwStyle, hMenu, msg_result);
 
-  /* If our OS is natively ASCII, use the ASCII version */
-  if (!(GetVersion() & 0x80000000))  /* NT */
-    return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
+  /* If our OS is natively ANSI, use the ANSI version */
+  if (GetVersion() & 0x80000000)  /* not NT */
+  {
+    TRACE("fallback to ANSI, ver 0x%08x\n", GetVersion());
+    return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, msg_result);
+  }
 
   /* Create Window class */
   wc.style         = 0;
@@ -2829,19 +2919,17 @@ HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle
   wc.lpszMenuName  = NULL;
   wc.lpszClassName = szClass;
 
-  SHRegisterClassW(&wc); /* Register class */
-
-  /* FIXME: Set extra bits in dwExStyle */
+  SHRegisterClassW(&wc);
 
   hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
                          hWndParent, hMenu, shlwapi_hInstance, 0);
   if (hWnd)
   {
-    SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
+    SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, msg_result);
 
-    if (wndProc)
-      SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
+    if (wndProc) SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
   }
+
   return hWnd;
 }
 
@@ -2861,7 +2949,8 @@ HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle
  */
 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
 {
-  return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
+    TRACE("%p %p %p\n", hWnd, lpFolder, lpApidl);
+    return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
 }
 
 /*************************************************************************
@@ -3376,12 +3465,12 @@ UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags,
 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
 {
   IContextMenu *iContext;
-  HRESULT hRet = E_FAIL;
+  HRESULT hRet;
 
-  TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
+  TRACE("(%p, %p, %p, %d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
 
   if (!lpFolder)
-    return hRet;
+    return E_FAIL;
 
   /* Get the context menu from the shell folder */
   hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
@@ -3401,7 +3490,7 @@ HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST
       if (SUCCEEDED(hQuery))
       {
         if (bInvokeDefault &&
-            (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
+            (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != (UINT)-1)
         {
           CMINVOKECOMMANDINFO cmIci;
           /* Invoke the default item */
@@ -3810,7 +3899,7 @@ DWORD WINAPI SHSendMessageBroadcastW(UINT uMsg, WPARAM wParam, LPARAM lParam)
  */
 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
 {
-    return CLSIDFromString((LPOLESTR)idstr, id);
+    return CLSIDFromString((LPCOLESTR)idstr, id);
 }
 
 /*************************************************************************
@@ -4171,18 +4260,24 @@ BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
  */
 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
 {
- MENUITEMINFOW mi;
- INT nCount = GetMenuItemCount(hMenu), nIter = 0;
+    MENUITEMINFOW mi;
+    INT nCount = GetMenuItemCount(hMenu), nIter = 0;
+
+    TRACE("%p %u\n", hMenu, wID);
 
- while (nIter < nCount)
- {
-   mi.cbSize = sizeof(mi);
-   mi.fMask = MIIM_ID;
-   if (GetMenuItemInfoW(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
-     return nIter;
-   nIter++;
- }
- return -1;
+    while (nIter < nCount)
+    {
+        mi.cbSize = sizeof(mi);
+        mi.fMask = MIIM_ID;
+        if (GetMenuItemInfoW(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
+        {
+            TRACE("ret %d\n", nIter);
+            return nIter;
+        }
+        nIter++;
+    }
+
+    return -1;
 }
 
 /*************************************************************************
@@ -4192,6 +4287,7 @@ INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
  */
 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
 {
+    TRACE("%p %u\n", hMenu, uID);
     return GetMenuPosFromID(hMenu, uID);
 }
 
@@ -4270,10 +4366,10 @@ BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
 /***********************************************************************
  *             SHGetShellKey (SHLWAPI.@)
  */
-DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
+HKEY WINAPI SHGetShellKey(DWORD flags, LPCWSTR sub_key, BOOL create)
 {
-    FIXME("(%x, %x, %x): stub\n", a, b, c);
-    return 0x50;
+    FIXME("(0x%08x, %s, %d): stub\n", flags, debugstr_w(sub_key), create);
+    return (HKEY)0x50;
 }
 
 /***********************************************************************
@@ -4422,20 +4518,6 @@ INT WINAPIV ShellMessageBoxWrapW(HINSTANCE hInstance, HWND hWnd, LPCWSTR lpText,
     return ret;
 }
 
-HRESULT WINAPI IUnknown_QueryServiceExec(IUnknown *unk, REFIID service, REFIID clsid,
-                                         DWORD x1, DWORD x2, DWORD x3, void **ppvOut)
-{
-    FIXME("%p %s %s %08x %08x %08x %p\n", unk,
-          debugstr_guid(service), debugstr_guid(clsid), x1, x2, x3, ppvOut);
-    return E_NOTIMPL;
-}
-
-HRESULT WINAPI IUnknown_ProfferService(IUnknown *unk, void *x0, void *x1, void *x2)
-{
-    FIXME("%p %p %p %p\n", unk, x0, x1, x2);
-    return E_NOTIMPL;
-}
-
 /***********************************************************************
  *              ZoneComputePaneSize [SHLWAPI.382]
  */
index d899232..367046b 100644 (file)
 216 stdcall -noname SHAnsiToUnicodeCP(long str ptr long)
 217 stdcall -noname SHUnicodeToAnsi(wstr ptr ptr)
 218 stdcall -noname SHUnicodeToAnsiCP(long wstr ptr long)
-219 stdcall -noname QISearch(long long long long)
+219 stdcall QISearch(long long long long)
 220 stdcall -noname SHSetDefaultDialogFont(ptr long)
 221 stdcall -noname SHRemoveDefaultDialogFont(ptr)
 222 stdcall -noname SHGlobalCounterCreate(long)
index 958a842..cd83b45 100644 (file)
@@ -278,7 +278,8 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
 {
     HRESULT hr = S_OK;
     DWORD EscapeFlags;
-    LPWSTR lpszUrlCpy, wk1, wk2, mp, mp2, root;
+    LPCWSTR wk1, root;
+    LPWSTR lpszUrlCpy, wk2, mp, mp2;
     INT state;
     DWORD nByteLen, nLen, nWkLen;
     WCHAR slash = '/';
@@ -322,7 +323,7 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
      *         6   have location (found /) save root location
      */
 
-    wk1 = (LPWSTR)pszUrl;
+    wk1 = pszUrl;
     wk2 = lpszUrlCpy;
     state = 0;
 
@@ -662,7 +663,7 @@ HRESULT WINAPI UrlCombineW(LPCWSTR pszBase, LPCWSTR pszRelative,
             }
         }
 
-        /* If there is a '#' and the characters immediately preceeding it are
+        /* If there is a '#' and the characters immediately preceding it are
          * ".htm[l]", then begin looking for the last leaf starting from
          * the '#'. Otherwise the '#' is not meaningful and just start
          * looking from the end. */
@@ -1718,6 +1719,9 @@ BOOL WINAPI UrlIsA(LPCSTR pszUrl, URLIS Urlis)
 
     TRACE("(%s %d)\n", debugstr_a(pszUrl), Urlis);
 
+    if(!pszUrl)
+        return FALSE;
+
     switch (Urlis) {
 
     case URLIS_OPAQUE:
@@ -1768,6 +1772,9 @@ BOOL WINAPI UrlIsW(LPCWSTR pszUrl, URLIS Urlis)
 
     TRACE("(%s %d)\n", debugstr_w(pszUrl), Urlis);
 
+    if(!pszUrl)
+        return FALSE;
+
     switch (Urlis) {
 
     case URLIS_OPAQUE:
index 018c178..3e582ec 100644 (file)
@@ -19,7 +19,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-
 #include <stdarg.h>
 #include <string.h>
 
@@ -31,6 +30,7 @@
 #include "objbase.h"
 #include "initguid.h"
 #include "sti.h"
+#include "wia_lh.h"
 
 #include "wine/debug.h"
 #include "wine/unicode.h"
@@ -395,8 +395,11 @@ static struct regsvr_interface const interface_list[] = {
     { NULL }                   /* list terminator */
 };
 
+extern HRESULT WINAPI STI_DllRegisterServer(void) DECLSPEC_HIDDEN;
+extern HRESULT WINAPI STI_DllUnregisterServer(void) DECLSPEC_HIDDEN;
+
 /***********************************************************************
- *             DllRegisterServer (INETCOMM.@)
+ *             DllRegisterServer (STI.@)
  */
 HRESULT WINAPI DllRegisterServer(void)
 {
@@ -404,14 +407,16 @@ HRESULT WINAPI DllRegisterServer(void)
 
     TRACE("\n");
 
-    hr = register_coclasses(coclass_list);
+    hr = STI_DllRegisterServer();
+    if (SUCCEEDED(hr))
+        hr = register_coclasses(coclass_list);
     if (SUCCEEDED(hr))
        hr = register_interfaces(interface_list);
     return hr;
 }
 
 /***********************************************************************
- *             DllUnregisterServer (INETCOMM.@)
+ *             DllUnregisterServer (STI.@)
  */
 HRESULT WINAPI DllUnregisterServer(void)
 {
@@ -422,5 +427,7 @@ HRESULT WINAPI DllUnregisterServer(void)
     hr = unregister_coclasses(coclass_list);
     if (SUCCEEDED(hr))
        hr = unregister_interfaces(interface_list);
+    if (SUCCEEDED(hr))
+        hr = STI_DllUnregisterServer();
     return hr;
 }
diff --git a/dll/win32/sti/sti.c b/dll/win32/sti/sti.c
new file mode 100644 (file)
index 0000000..974bd06
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2002 Aric Stewart for CodeWeavers
+ * Copyright (C) 2009 Damjan Jovanovic
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winerror.h"
+#include "objbase.h"
+#include "sti.h"
+
+#include "sti_private.h"
+
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(sti);
+
+static const WCHAR registeredAppsLaunchPath[] = {
+    'S','O','F','T','W','A','R','E','\\',
+    'M','i','c','r','o','s','o','f','t','\\',
+    'W','i','n','d','o','w','s','\\',
+    'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+    'S','t','i','l','l','I','m','a','g','e','\\',
+    'R','e','g','i','s','t','e','r','e','d',' ','A','p','p','l','i','c','a','t','i','o','n','s',0
+};
+
+static inline stillimage *impl_from_StillImageW(IStillImageW *iface)
+{
+    return (stillimage *)((char*)iface - FIELD_OFFSET(stillimage, lpVtbl));
+}
+
+static HRESULT WINAPI stillimagew_QueryInterface(IStillImageW *iface, REFIID riid, void **ppvObject)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    TRACE("(%p %s %p)\n", This, debugstr_guid(riid), ppvObject);
+    return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObject);
+}
+
+static ULONG WINAPI stillimagew_AddRef(IStillImageW *iface)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    return IUnknown_AddRef(This->pUnkOuter);
+}
+
+static ULONG WINAPI stillimagew_Release(IStillImageW *iface)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    return IUnknown_Release(This->pUnkOuter);
+}
+
+static HRESULT WINAPI stillimagew_Initialize(IStillImageW *iface, HINSTANCE hinst, DWORD dwVersion)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    TRACE("(%p, %p, 0x%X)\n", This, hinst, dwVersion);
+    return S_OK;
+}
+
+static HRESULT WINAPI stillimagew_GetDeviceList(IStillImageW *iface, DWORD dwType, DWORD dwFlags,
+                                                DWORD *pdwItemsReturned, LPVOID *ppBuffer)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %u, 0x%X, %p, %p): stub\n", This, dwType, dwFlags, pdwItemsReturned, ppBuffer);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI stillimagew_GetDeviceInfo(IStillImageW *iface, LPWSTR pwszDeviceName,
+                                                LPVOID *ppBuffer)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), ppBuffer);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI stillimagew_CreateDevice(IStillImageW *iface, LPWSTR pwszDeviceName, DWORD dwMode,
+                                               PSTIDEVICEW *pDevice, LPUNKNOWN pUnkOuter)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %s, %u, %p, %p): stub\n", This, debugstr_w(pwszDeviceName), dwMode, pDevice, pUnkOuter);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI stillimagew_GetDeviceValue(IStillImageW *iface, LPWSTR pwszDeviceName, LPWSTR pValueName,
+                                                 LPDWORD pType, LPBYTE pData, LPDWORD cbData)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %s, %s, %p, %p, %p): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pValueName),
+        pType, pData, cbData);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI stillimagew_SetDeviceValue(IStillImageW *iface, LPWSTR pwszDeviceName, LPWSTR pValueName,
+                                                 DWORD type, LPBYTE pData, DWORD cbData)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %s, %s, %u, %p, %u): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pValueName),
+        type, pData, cbData);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI stillimagew_GetSTILaunchInformation(IStillImageW *iface, LPWSTR pwszDeviceName,
+                                                          DWORD *pdwEventCode, LPWSTR pwszEventName)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %p, %p, %p): stub\n", This, pwszDeviceName,
+        pdwEventCode, pwszEventName);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI stillimagew_RegisterLaunchApplication(IStillImageW *iface, LPWSTR pwszAppName,
+                                                            LPWSTR pwszCommandLine)
+{
+    static const WCHAR format[] = {'%','s',' ','%','s',0};
+    static const WCHAR commandLineSuffix[] = {
+        '/','S','t','i','D','e','v','i','c','e',':','%','1',' ',
+        '/','S','t','i','E','v','e','n','t',':','%','2',0};
+    HKEY registeredAppsKey = NULL;
+    DWORD ret;
+    HRESULT hr = S_OK;
+    stillimage *This = impl_from_StillImageW(iface);
+
+    TRACE("(%p, %s, %s)\n", This, debugstr_w(pwszAppName), debugstr_w(pwszCommandLine));
+
+    ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, registeredAppsLaunchPath, &registeredAppsKey);
+    if (ret == ERROR_SUCCESS)
+    {
+        WCHAR *value = HeapAlloc(GetProcessHeap(), 0,
+            (lstrlenW(pwszCommandLine) + 1 + lstrlenW(commandLineSuffix) + 1) * sizeof(WCHAR));
+        if (value)
+        {
+            sprintfW(value, format, pwszCommandLine, commandLineSuffix);
+            ret = RegSetValueExW(registeredAppsKey, pwszAppName, 0,
+                REG_SZ, (BYTE*)value, (lstrlenW(value)+1)*sizeof(WCHAR));
+            if (ret != ERROR_SUCCESS)
+                hr = HRESULT_FROM_WIN32(ret);
+            HeapFree(GetProcessHeap(), 0, value);
+        }
+        else
+            hr = E_OUTOFMEMORY;
+        RegCloseKey(registeredAppsKey);
+    }
+    else
+        hr = HRESULT_FROM_WIN32(ret);
+    return hr;
+}
+
+static HRESULT WINAPI stillimagew_UnregisterLaunchApplication(IStillImageW *iface, LPWSTR pwszAppName)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    HKEY registeredAppsKey = NULL;
+    DWORD ret;
+    HRESULT hr = S_OK;
+
+    TRACE("(%p, %s)\n", This, debugstr_w(pwszAppName));
+
+    ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, registeredAppsLaunchPath, &registeredAppsKey);
+    if (ret == ERROR_SUCCESS)
+    {
+        ret = RegDeleteValueW(registeredAppsKey, pwszAppName);
+        if (ret != ERROR_SUCCESS)
+            hr = HRESULT_FROM_WIN32(ret);
+        RegCloseKey(registeredAppsKey);
+    }
+    else
+        hr = HRESULT_FROM_WIN32(ret);
+    return hr;
+}
+
+static HRESULT WINAPI stillimagew_EnableHwNotifications(IStillImageW *iface, LPCWSTR pwszDeviceName,
+                                                        BOOL bNewState)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %s, %u): stub\n", This, debugstr_w(pwszDeviceName), bNewState);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI stillimagew_GetHwNotificationState(IStillImageW *iface, LPCWSTR pwszDeviceName,
+                                                         BOOL *pbCurrentState)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), pbCurrentState);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI stillimagew_RefreshDeviceBus(IStillImageW *iface, LPCWSTR pwszDeviceName)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %s): stub\n", This, debugstr_w(pwszDeviceName));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI stillimagew_LaunchApplicationForDevice(IStillImageW *iface, LPWSTR pwszDeviceName,
+                                                             LPWSTR pwszAppName, LPSTINOTIFY pStiNotify)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %s, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pwszAppName),
+        pStiNotify);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI stillimagew_SetupDeviceParameters(IStillImageW *iface, PSTI_DEVICE_INFORMATIONW pDevInfo)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %p): stub\n", This, pDevInfo);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI stillimagew_WriteToErrorLog(IStillImageW *iface, DWORD dwMessageType, LPCWSTR pszMessage)
+{
+    stillimage *This = impl_from_StillImageW(iface);
+    FIXME("(%p, %u, %s): stub\n", This, dwMessageType, debugstr_w(pszMessage));
+    return E_NOTIMPL;
+}
+
+static const struct IStillImageWVtbl stillimagew_vtbl =
+{
+    stillimagew_QueryInterface,
+    stillimagew_AddRef,
+    stillimagew_Release,
+    stillimagew_Initialize,
+    stillimagew_GetDeviceList,
+    stillimagew_GetDeviceInfo,
+    stillimagew_CreateDevice,
+    stillimagew_GetDeviceValue,
+    stillimagew_SetDeviceValue,
+    stillimagew_GetSTILaunchInformation,
+    stillimagew_RegisterLaunchApplication,
+    stillimagew_UnregisterLaunchApplication,
+    stillimagew_EnableHwNotifications,
+    stillimagew_GetHwNotificationState,
+    stillimagew_RefreshDeviceBus,
+    stillimagew_LaunchApplicationForDevice,
+    stillimagew_SetupDeviceParameters,
+    stillimagew_WriteToErrorLog
+};
+
+static inline stillimage *impl_from_InternalUnknown(IUnknown *iface)
+{
+    return (stillimage *)((char*)iface - FIELD_OFFSET(stillimage, lpInternalUnkVtbl));
+}
+
+static HRESULT WINAPI Internal_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
+{
+    stillimage *This = impl_from_InternalUnknown(iface);
+
+    TRACE("(%p %s %p)\n", This, debugstr_guid(riid), ppvObject);
+
+    if (IsEqualGUID(riid, &IID_IUnknown))
+        *ppvObject = iface;
+    else if (IsEqualGUID(riid, &IID_IStillImageW))
+        *ppvObject = &This->lpVtbl;
+    else
+    {
+        if (IsEqualGUID(riid, &IID_IStillImageA))
+            FIXME("interface IStillImageA is unsupported on Windows Vista too, please report if it's needed\n");
+        else
+            FIXME("interface %s not implemented\n", debugstr_guid(riid));
+        *ppvObject = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*) *ppvObject);
+    return S_OK;
+}
+
+static ULONG WINAPI Internal_AddRef(IUnknown *iface)
+{
+    stillimage *This = impl_from_InternalUnknown(iface);
+    return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI Internal_Release(IUnknown *iface)
+{
+    ULONG ref;
+    stillimage *This = impl_from_InternalUnknown(iface);
+
+    ref = InterlockedDecrement(&This->ref);
+    if (ref == 0)
+        HeapFree(GetProcessHeap(), 0, This);
+    return ref;
+}
+
+static const struct IUnknownVtbl internal_unk_vtbl =
+{
+    Internal_QueryInterface,
+    Internal_AddRef,
+    Internal_Release
+};
+
+/******************************************************************************
+ *           StiCreateInstanceA   (STI.@)
+ */
+HRESULT WINAPI StiCreateInstanceA(HINSTANCE hinst, DWORD dwVer, PSTIA *ppSti, LPUNKNOWN pUnkOuter)
+{
+    FIXME("(%p, %u, %p, %p): stub, unimplemented on Windows Vista too, please report if it's needed\n", hinst, dwVer, ppSti, pUnkOuter);
+    return STG_E_UNIMPLEMENTEDFUNCTION;
+}
+
+/******************************************************************************
+ *           StiCreateInstanceW   (STI.@)
+ */
+HRESULT WINAPI StiCreateInstanceW(HINSTANCE hinst, DWORD dwVer, PSTIW *ppSti, LPUNKNOWN pUnkOuter)
+{
+    stillimage *This;
+    HRESULT hr;
+
+    TRACE("(%p, %u, %p, %p)\n", hinst, dwVer, ppSti, pUnkOuter);
+
+    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(stillimage));
+    if (This)
+    {
+        This->lpVtbl = &stillimagew_vtbl;
+        This->lpInternalUnkVtbl = &internal_unk_vtbl;
+        if (pUnkOuter)
+            This->pUnkOuter = pUnkOuter;
+        else
+            This->pUnkOuter = (IUnknown*) &This->lpInternalUnkVtbl;
+        This->ref = 1;
+
+        hr = IStillImage_Initialize((IStillImageW*) &This->lpVtbl, hinst, dwVer);
+        if (SUCCEEDED(hr))
+        {
+            if (pUnkOuter)
+                *ppSti = (IStillImageW*) &This->lpInternalUnkVtbl;
+            else
+                *ppSti = (IStillImageW*) &This->lpVtbl;
+        }
+    }
+    else
+        hr = E_OUTOFMEMORY;
+
+    return hr;
+}
index 592c5f1..edce67a 100644 (file)
@@ -8,11 +8,29 @@
        <include base="ReactOS">include/reactos/wine</include>
        <redefine name="_WIN32_WINNT">0x600</redefine>
        <define name="__WINESRC__" />
+       <define name="ENTRY_PREFIX">STI_</define>
+       <define name="PROXY_DELEGATION" />
+       <define name="REGISTER_PROXY_DLL" />
+
        <file>regsvr.c</file>
+       <file>sti.c</file>
        <file>sti_main.c</file>
+       <file>sti_wia.idl</file>
        <library>wine</library>
-       <library>advapi32</library>
+       <library>sti_proxy</library>
        <library>ole32</library>
+       <library>oleaut32</library>
+       <library>rpcrt4</library>
+       <library>advapi32</library>
+       <library>pseh</library>
+       <library>uuid</library>
        <library>ntdll</library>
 </module>
+<module name="sti_proxy" type="rpcproxy" allowwarnings="true">
+       <define name="__WINESRC__" />
+       <define name="ENTRY_PREFIX">STI_</define>
+       <define name="REGISTER_PROXY_DLL"/>
+       <define name="PROXY_DELEGATION" />
+       <file>sti_wia.idl</file>
+</module>
 </group>
index 186f382..300e7fa 100644 (file)
@@ -1,7 +1,7 @@
-@ stub DllCanUnloadNow
-@ stub DllGetClassObject
+@ stdcall -private DllCanUnloadNow()
+@ stdcall -private DllGetClassObject(ptr ptr ptr)
 @ stdcall -private DllRegisterServer()
 @ stdcall -private DllUnregisterServer()
-@ stdcall StiCreateInstance(ptr long ptr ptr)
+@ stdcall StiCreateInstance(ptr long ptr ptr) StiCreateInstanceW
 @ stdcall StiCreateInstanceA(ptr long ptr ptr)
 @ stdcall StiCreateInstanceW(ptr long ptr ptr)
index 1d4e6ad..711c17f 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2002 Aric Stewart for CodeWeavers
+ * Copyright (C) 2009 Damjan Jovanovic
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 
 #include <stdarg.h>
 
+#define COBJMACROS
+
 #include "windef.h"
 #include "winbase.h"
 #include "winreg.h"
 #include "winerror.h"
+#include "objbase.h"
+#include "sti.h"
 
-/******************************************************************************
- *           StiCreateInstance   (STI.@)
- */
-HRESULT WINAPI StiCreateInstance( HINSTANCE a, DWORD b, LPVOID c, LPVOID d)
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(sti);
+
+extern HRESULT WINAPI STI_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN;
+extern BOOL WINAPI STI_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
+
+typedef HRESULT (*fnCreateInstance)(REFIID riid, IUnknown *pUnkOuter, LPVOID *ppObj);
+
+typedef struct
+{
+    const struct IClassFactoryVtbl *vtbl;
+    fnCreateInstance pfnCreateInstance;
+} sti_cf;
+
+static inline sti_cf *impl_from_IClassFactory( IClassFactory *iface )
+{
+    return (sti_cf *)((char *)iface - FIELD_OFFSET( sti_cf, vtbl ));
+}
+
+static HRESULT sti_create( REFIID riid, IUnknown *pUnkOuter, LPVOID *ppObj )
+{
+    if (pUnkOuter != NULL && !IsEqualIID(riid, &IID_IUnknown))
+        return CLASS_E_NOAGGREGATION;
+
+    if (IsEqualGUID(riid, &IID_IUnknown))
+        return StiCreateInstanceW(GetCurrentProcess(), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, (PSTIW*) ppObj, pUnkOuter);
+    else if (IsEqualGUID(riid, &IID_IStillImageW))
+        return StiCreateInstanceW(GetCurrentProcess(), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, (PSTIW*) ppObj, NULL);
+    else if (IsEqualGUID(riid, &IID_IStillImageA))
+        return StiCreateInstanceA(GetCurrentProcess(), STI_VERSION_REAL, (PSTIA*) ppObj, NULL);
+    else
+    {
+        FIXME("no interface %s\n", debugstr_guid(riid));
+        return E_NOINTERFACE;
+    }
+}
+
+static HRESULT WINAPI sti_cf_QueryInterface( IClassFactory *iface, REFIID riid, LPVOID *ppobj )
+{
+    if (IsEqualGUID(riid, &IID_IUnknown) ||
+        IsEqualGUID(riid, &IID_IClassFactory))
+    {
+        IClassFactory_AddRef( iface );
+        *ppobj = iface;
+        return S_OK;
+    }
+    FIXME("interface %s not implemented\n", debugstr_guid(riid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI sti_cf_AddRef( IClassFactory *iface )
+{
+    return 2;
+}
+
+static ULONG WINAPI sti_cf_Release( IClassFactory *iface )
 {
-    return STG_E_UNIMPLEMENTEDFUNCTION;
+    return 1;
+}
+
+static HRESULT WINAPI sti_cf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOuter,
+                                             REFIID riid, LPVOID *ppobj )
+{
+    sti_cf *This = impl_from_IClassFactory( iface );
+    HRESULT r;
+    IUnknown *punk;
+
+    TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj);
+
+    *ppobj = NULL;
+
+    r = This->pfnCreateInstance( riid, pOuter, (LPVOID *)&punk );
+    if (FAILED(r))
+        return r;
+
+    r = IUnknown_QueryInterface( punk, riid, ppobj );
+    if (FAILED(r))
+        return r;
+
+    IUnknown_Release( punk );
+    return r;
+}
+
+static HRESULT WINAPI sti_cf_LockServer( IClassFactory *iface, BOOL dolock )
+{
+    FIXME("(%p)->(%d)\n", iface, dolock);
+    return S_OK;
+}
+
+static const struct IClassFactoryVtbl sti_cf_vtbl =
+{
+    sti_cf_QueryInterface,
+    sti_cf_AddRef,
+    sti_cf_Release,
+    sti_cf_CreateInstance,
+    sti_cf_LockServer
+};
+
+static sti_cf the_sti_cf = { &sti_cf_vtbl, sti_create };
+
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+    TRACE("(0x%p, %d, %p)\n",hInstDLL,fdwReason,lpvReserved);
+
+    if (fdwReason == DLL_WINE_PREATTACH)
+        return FALSE;
+    return STI_DllMain(hInstDLL, fdwReason, lpvReserved);
 }
 
 /******************************************************************************
- *           StiCreateInstanceA   (STI.@)
+ *           DllGetClassObject   (STI.@)
  */
-HRESULT WINAPI StiCreateInstanceA( HINSTANCE a, DWORD b, LPVOID c, LPVOID d)
+HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv )
 {
-    return STG_E_UNIMPLEMENTEDFUNCTION;
+    IClassFactory *cf = NULL;
+
+    TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
+
+    if (IsEqualGUID( rclsid, &CLSID_Sti ))
+    {
+       cf = (IClassFactory *)&the_sti_cf.vtbl;
+    }
+
+    if (cf)
+        return IClassFactory_QueryInterface( cf, iid, ppv );
+    return STI_DllGetClassObject( rclsid, iid, ppv );
 }
 
 /******************************************************************************
- *           StiCreateInstanceW   (STI.@)
+ *           DllCanUnloadNow   (STI.@)
  */
-HRESULT WINAPI StiCreateInstanceW( HINSTANCE a, DWORD b, LPVOID c, LPVOID d)
+HRESULT WINAPI DllCanUnloadNow( void )
 {
-    return STG_E_UNIMPLEMENTEDFUNCTION;
+    return S_FALSE;
 }
diff --git a/dll/win32/sti/sti_private.h b/dll/win32/sti/sti_private.h
new file mode 100644 (file)
index 0000000..b5e106b
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * STI private definitions
+ *
+ * Copyright 2009 Damjan Jovanovic
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __STI_PRIVATE__
+#define __STI_PRIVATE__
+
+typedef struct _stillimage
+{
+    const struct IStillImageWVtbl *lpVtbl;
+    const struct IUnknownVtbl *lpInternalUnkVtbl;
+    IUnknown *pUnkOuter;
+    LONG ref;
+} stillimage;
+
+#endif /* __STI_PRIVATE__ */
diff --git a/dll/win32/sti/sti_wia.idl b/dll/win32/sti/sti_wia.idl
new file mode 100644 (file)
index 0000000..aaac943
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2009 Damjan Jovanovic
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wia_lh.idl"
index ba3f998..bc76a2e 100644 (file)
@@ -213,7 +213,7 @@ BEGIN
     IDS_GAMES           "Giochi"
     IDS_CMT_SOLITAIRE   "Solitario"
     IDS_CMT_WINEMINE    "Campo minato"
-       IDS_CMT_SPIDER      "Spider Solitaire"
+       IDS_CMT_SPIDER      "Spider"
 END
 
 STRINGTABLE
@@ -235,7 +235,7 @@ BEGIN
     IDS_SYS_ENTERTAINMENT       "Divertimento"
     IDS_CMT_MPLAY32             "Esegui Multimedia Player"
     IDS_CMT_SNDVOL32            "Esegui Controllo Volume"
-    IDS_CMT_SNDREC32            "Launch Sound Recorder"
+    IDS_CMT_SNDREC32            "Esegui il Registratore di suonoi"
 END
 
 STRINGTABLE
@@ -255,7 +255,7 @@ STRINGTABLE
 BEGIN
     IDS_SHORT_CMD        "Prompt dei comandi.lnk"
     IDS_SHORT_EXPLORER   "ReactOS Explorer.lnk"
-    IDS_SHORT_DOWNLOADER "ReactOS Applications Manager.lnk"
+    IDS_SHORT_DOWNLOADER "ReactOS gestione applicazioni.lnk"
     IDS_SHORT_SERVICE    "Service Manager.lnk"
     IDS_SHORT_DEVICE     "Device Manager.lnk"
     IDS_SHORT_MPLAY32    "Multimedia Player.lnk"
@@ -271,12 +271,12 @@ BEGIN
     IDS_SHORT_RDESKTOP   "Remote Desktop.lnk"
     IDS_SHORT_KBSWITCH   "Layout di tastiera.lnk"
     IDS_SHORT_EVENTVIEW  "Visualizzatore Eventi.lnk"
-    IDS_SHORT_MSCONFIG   "Configuratione del sistema.lnk"
+    IDS_SHORT_MSCONFIG   "Configurazione del sistema.lnk"
     IDS_SHORT_SNDVOL32   "Controllo Volume.lnk"
     IDS_SHORT_SNDREC32   "Audiorecorder.lnk"
     IDS_SHORT_DXDIAG     "ReactX Diagnostica.lnk"
     IDS_SHORT_PAINT      "Paint.lnk"
-    IDS_SHORT_SPIDER     "Spider Solitaire.lnk"
+       IDS_SHORT_SPIDER     "Spider.lnk"
 END
 
 STRINGTABLE
index 7a084f5..63d6bc2 100644 (file)
@@ -1960,6 +1960,7 @@ FinishDlgProc(HWND hwndDlg,
       case WM_DESTROY:
          {
            SetupIsActive(0);
+           PostQuitMessage(0);
            return TRUE;
          }
 
@@ -1999,7 +2000,7 @@ FinishDlgProc(HWND hwndDlg,
                 break;
 
               case PSN_WIZFINISH:
-                /* Handle a Finish button click, if necessary */
+                DestroyWindow(GetParent(hwndDlg));
                 break;
 
               default:
@@ -2269,6 +2270,8 @@ InstallWizard(VOID)
   HPROPSHEETPAGE ahpsp[8];
   PROPSHEETPAGE psp = {0};
   UINT nPages = 0;
+  HWND hWnd;
+  MSG msg;
 
   /* Clear setup data */
   ZeroMemory(&SetupData, sizeof(SETUPDATA));
@@ -2345,7 +2348,7 @@ InstallWizard(VOID)
 
   /* Create the property sheet */
   psh.dwSize = sizeof(PROPSHEETHEADER);
-  psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
+  psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER | PSH_MODELESS;
   psh.hInstance = hDllInstance;
   psh.hwndParent = NULL;
   psh.nPages = nPages;
@@ -2358,7 +2361,17 @@ InstallWizard(VOID)
   SetupData.hTitleFont = CreateTitleFont();
 
   /* Display the wizard */
-  PropertySheet(&psh);
+  hWnd = (HWND)PropertySheet(&psh);
+  ShowWindow(hWnd, SW_SHOW);
+
+  while (GetMessage(&msg, NULL, 0, 0)) 
+  {
+    if(!IsDialogMessage(hWnd, &msg))
+    {
+      TranslateMessage(&msg);
+      DispatchMessage(&msg);
+    }
+  }
 
   DeleteObject(SetupData.hTitleFont);
 }
index 07d6fc2..29b8532 100644 (file)
@@ -155,7 +155,7 @@ HWND get_notif_hwnd(void)
             NULL
         };
 
-        wndclass.hInstance = URLMON_hInstance;
+        wndclass.hInstance = hProxyDll;
 
         wnd_class = RegisterClassExW(&wndclass);
         if (!wnd_class && GetLastError() == ERROR_CLASS_ALREADY_EXISTS)
@@ -164,7 +164,7 @@ HWND get_notif_hwnd(void)
 
     tls_data->notif_hwnd = CreateWindowExW(0, wszURLMonikerNotificationWindow,
             wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE,
-            NULL, URLMON_hInstance, NULL);
+            NULL, hProxyDll, NULL);
     if(tls_data->notif_hwnd)
         tls_data->notif_hwnd_cnt++;
 
index 9e27825..6e417ac 100644 (file)
@@ -560,7 +560,7 @@ static HRESULT register_inf(BOOL doregister)
     hAdvpack = LoadLibraryW(wszAdvpack);
     pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
 
-    hres = pRegInstall(URLMON_hInstance, doregister ? "RegisterDll" : "UnregisterDll", &strtable);
+    hres = pRegInstall(hProxyDll, doregister ? "RegisterDll" : "UnregisterDll", &strtable);
 
     for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++)
         heap_free(pse[i].pszValue);
index 272884e..edaad42 100644 (file)
@@ -34,7 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
 
 LONG URLMON_refCount = 0;
 
-HINSTANCE URLMON_hInstance = 0;
 static HMODULE hCabinet = NULL;
 static DWORD urlmon_tls = TLS_OUT_OF_INDEXES;
 
@@ -144,9 +143,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
 {
     TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad);
 
+    URLMON_DllMain( hinstDLL, fdwReason, fImpLoad );
+
     switch(fdwReason) {
     case DLL_PROCESS_ATTACH:
-        URLMON_hInstance = hinstDLL;
         init_session(TRUE);
         break;
 
index 8db786b..071af8d 100644 (file)
@@ -36,7 +36,7 @@
 #include "wine/unicode.h"
 #include "wine/list.h"
 
-extern HINSTANCE URLMON_hInstance;
+extern HINSTANCE hProxyDll DECLSPEC_HIDDEN;
 extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
 extern HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
 extern HRESULT StdURLMoniker_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
@@ -48,6 +48,7 @@ extern HRESULT GopherProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
 extern HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
 extern HRESULT MimeFilter_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
 
+extern BOOL WINAPI URLMON_DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) DECLSPEC_HIDDEN;
 extern HRESULT WINAPI URLMON_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN;
 extern HRESULT WINAPI URLMON_DllRegisterServer(void) DECLSPEC_HIDDEN;
 extern HRESULT WINAPI URLMON_DllUnregisterServer(void) DECLSPEC_HIDDEN;
index 71a0719..d45ba07 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2009 Piotr Caban for Codeweavers
+ * Copyright 2009 Piotr Caban for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
index b945563..6ff8f04 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2009 Piotr Caban for Codeweavers
+ * Copyright 2009 Piotr Caban for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
index 1f448bd..8b4003b 100644 (file)
@@ -829,7 +829,7 @@ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, const RECT *rc)
  */
 static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
 {
-    RECT     rc, focus_rect, r;
+    RECT     rc, r;
     UINT     dtFlags, uState;
     HPEN     hOldPen;
     HBRUSH   hOldBrush;
@@ -865,13 +865,11 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
             Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
        InflateRect( &rc, -1, -1 );
     }
-    
-    focus_rect = rc;
 
     /* completely skip the drawing if only focus has changed */
     if (action == ODA_FOCUS) goto draw_focus;
 
-    uState = DFCS_BUTTONPUSH | DFCS_ADJUSTRECT;
+    uState = DFCS_BUTTONPUSH;
 
     if (style & BS_FLAT)
         uState |= DFCS_MONO;
@@ -898,8 +896,6 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
     if (pushedState)
        OffsetRect(&r, 1, 1);
 
-    IntersectClipRect(hDC, rc.left, rc.top, rc.right, rc.bottom);
-
     oldTxtColor = SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) );
 
     BUTTON_DrawLabel(hwnd, hDC, dtFlags, &r);
@@ -912,9 +908,8 @@ draw_focus:
     {
         if (!(get_ui_state(hwnd) & UISF_HIDEFOCUS))
         {
-            InflateRect( &focus_rect, -1, -1 );
-            IntersectRect(&focus_rect, &focus_rect, &rc);
-            DrawFocusRect( hDC, &focus_rect );
+            InflateRect( &rc, -2, -2 );
+            DrawFocusRect( hDC, &rc );
         }
     }
 
index b053f38..06608d8 100644 (file)
@@ -170,11 +170,11 @@ UserRealizePalette ( HDC hDC )
 static HPEN SysColorPens[COLOR_MENUBAR + 1];
 static HBRUSH SysColorBrushes[COLOR_MENUBAR + 1];
 
-DWORD
+DWORD_PTR
 WINAPI
 SetSysColorsTemp(const COLORREF *pPens,
                  const HBRUSH *pBrushes,
-                                DWORD n)
+                                DWORD_PTR n)
 {
     DWORD i;
 
@@ -183,7 +183,7 @@ SetSysColorsTemp(const COLORREF *pPens,
         /* allocate our structure to remember old colors */
         LPVOID pOldCol = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD)+n*sizeof(HPEN)+n*sizeof(HBRUSH));
         LPVOID p = pOldCol;
-        *(DWORD *)p = n; p = (char*)p + sizeof(DWORD);
+        *(DWORD_PTR *)p = n; p = (char*)p + sizeof(DWORD);
         memcpy(p, SysColorPens, n*sizeof(HPEN)); p = (char*)p + n*sizeof(HPEN);
         memcpy(p, SysColorBrushes, n*sizeof(HBRUSH)); p = (char*)p + n*sizeof(HBRUSH);
 
@@ -193,7 +193,7 @@ SetSysColorsTemp(const COLORREF *pPens,
             SysColorBrushes[i] = pBrushes[i];
         }
 
-        return (DWORD) pOldCol; /* FIXME: pointer truncation */
+        return (DWORD_PTR) pOldCol;
     }
     if (!pPens && !pBrushes) /* "restore" call */
     {
index ade437c..1178558 100644 (file)
@@ -3524,11 +3524,11 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT
 /***********************************************************************
  *           MenuExitTracking
  */
-static BOOL FASTCALL MenuExitTracking(HWND hWnd)
+static BOOL FASTCALL MenuExitTracking(HWND hWnd, BOOL bPopup)
 {
     TRACE("hwnd=%p\n", hWnd);
 
-    SendMessageW( hWnd, WM_EXITMENULOOP, 0, 0 );
+    SendMessageW( hWnd, WM_EXITMENULOOP, bPopup, 0 );
     ShowCaret(0);
     top_popup = 0;
     top_popup_hmenu = NULL;
@@ -3558,7 +3558,7 @@ VOID MenuTrackMouseMenuBar( HWND hWnd, ULONG ht, POINT pt)
 
         MenuInitTracking(hWnd, hMenu, FALSE, wFlags);
         MenuTrackMenu(hMenu, wFlags, pt.x, pt.y, hWnd, NULL);
-        MenuExitTracking(hWnd);
+        MenuExitTracking(hWnd, FALSE);
     }
 }
 
@@ -3633,7 +3633,7 @@ VOID MenuTrackKbdMenuBar(HWND hwnd, UINT wParam, WCHAR wChar)
 
 track_menu:
     MenuTrackMenu( hTrackMenu, wFlags, 0, 0, hwnd, NULL );
-    MenuExitTracking( hwnd );
+    MenuExitTracking( hwnd, FALSE );
 
 }
 
@@ -3660,7 +3660,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y,
     if (MenuShowPopup(Wnd, Menu, 0, Flags, x, y, 0, 0 ))
        ret = MenuTrackMenu(Menu, Flags | TPM_POPUPMENU, 0, 0, Wnd,
                            Tpm ? &Tpm->rcExclude : NULL);
-    MenuExitTracking(Wnd);
+    MenuExitTracking(Wnd, TRUE);
     return ret;
 }
 
index a582d53..4067447 100644 (file)
@@ -1,20 +1,6 @@
-/*
- * Copyright (C) 2004 Eric Kohl
- *               2008 Radek Liska
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+/* FILE:        dll/win32/devmgr/lang/cs-CZ.rc
+ * TRANSLATOR:  Radek Liska aka Black_Fox (radekliska at gmail dot com)
+ * UPDATED:     2010-01-07
  */
 
 LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
@@ -36,7 +22,7 @@ BEGIN
     IDS_TEMPLATES      "\8aablony"
     IDS_RECENT         "Poslední dokumenty"
     IDS_SENDTO         "SendTo"
-    IDS_PRINTHOOD      "okolní tiskárny"
+    IDS_PRINTHOOD      "Okolní tiskárny"
     IDS_NETHOOD        "Okolní sí\9d"
     IDS_LOCALSETTINGS  "Local Settings"
     IDS_LOCALAPPDATA   "Local Settings\\Data Aplikací"
index 796325c..ca422dd 100644 (file)
@@ -674,10 +674,6 @@ InitializeProfiles(VOID)
         }
     }
 
-    SetEnvironmentVariableW(L"ProgramFiles", szProfilesPath);
-    SetEnvironmentVariableW(L"CommonProgramFiles", szCommonFilesDirPath);
-
-
     DPRINT("Success\n");
 
     return TRUE;
diff --git a/dll/win32/usp10/bidi.c b/dll/win32/usp10/bidi.c
new file mode 100644 (file)
index 0000000..28b5d3e
--- /dev/null
@@ -0,0 +1,893 @@
+/*
+ * Uniscribe BiDirectional handling
+ *
+ * Copyright 2003 Shachar Shemesh
+ * Copyright 2007 Maarten Lankhorst
+ * Copyright 2010 CodeWeavers, Aric Stewart
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * Code derived from the modified reference implementation
+ * that was found in revision 17 of http://unicode.org/reports/tr9/
+ * "Unicode Standard Annex #9: THE BIDIRECTIONAL ALGORITHM"
+ *
+ * -- Copyright (C) 1999-2005, ASMUS, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of the Unicode data files and any associated documentation (the
+ * "Data Files") or Unicode software and any associated documentation (the
+ * "Software") to deal in the Data Files or Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, and/or sell copies of the Data Files or Software,
+ * and to permit persons to whom the Data Files or Software are furnished
+ * to do so, provided that (a) the above copyright notice(s) and this
+ * permission notice appear with all copies of the Data Files or Software,
+ * (b) both the above copyright notice(s) and this permission notice appear
+ * in associated documentation, and (c) there is clear notice in each
+ * modified Data File or in the Software as well as in the documentation
+ * associated with the Data File(s) or Software that the data or software
+ * has been modified.
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winnls.h"
+#include "usp10.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+
+#include "usp10_internal.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(bidi);
+
+#define ASSERT(x) do { if (!(x)) FIXME("assert failed: %s\n", #x); } while(0)
+#define MAX_LEVEL 61
+
+/* HELPER FUNCTIONS AND DECLARATIONS */
+
+/*------------------------------------------------------------------------
+    Bidirectional Character Types
+
+    as defined by the Unicode Bidirectional Algorithm Table 3-7.
+
+    Note:
+
+      The list of bidirectional character types here is not grouped the
+      same way as the table 3-7, since the numberic values for the types
+      are chosen to keep the state and action tables compact.
+------------------------------------------------------------------------*/
+enum directions
+{
+    /* input types */
+             /* ON MUST be zero, code relies on ON = N = 0 */
+    ON = 0,  /* Other Neutral */
+    L,       /* Left Letter */
+    R,       /* Right Letter */
+    AN,      /* Arabic Number */
+    EN,      /* European Number */
+    AL,      /* Arabic Letter (Right-to-left) */
+    NSM,     /* Non-spacing Mark */
+    CS,      /* Common Separator */
+    ES,      /* European Separator */
+    ET,      /* European Terminator (post/prefix e.g. $ and %) */
+
+    /* resolved types */
+    BN,      /* Boundary neutral (type of RLE etc after explicit levels) */
+
+    /* input types, */
+    S,       /* Segment Separator (TAB)        // used only in L1 */
+    WS,      /* White space                    // used only in L1 */
+    B,       /* Paragraph Separator (aka as PS) */
+
+    /* types for explicit controls */
+    RLO,     /* these are used only in X1-X9 */
+    RLE,
+    LRO,
+    LRE,
+    PDF,
+
+    /* resolved types, also resolved directions */
+    N = ON,  /* alias, where ON, WS and S are treated the same */
+};
+
+/* HELPER FUNCTIONS */
+/* the character type contains the C1_* flags in the low 12 bits */
+/* and the C2_* type in the high 4 bits */
+static __inline unsigned short get_char_typeW( WCHAR ch )
+{
+    WORD CharType;
+    GetStringTypeW(CT_CTYPE1, &ch, 1, &CharType);
+    return CharType;
+}
+
+/* Convert the libwine information to the direction enum */
+static void classify(LPCWSTR lpString, WORD *chartype, DWORD uCount, const SCRIPT_CONTROL *c)
+{
+    static const enum directions dir_map[16] =
+    {
+        L,  /* unassigned defaults to L */
+        L,
+        R,
+        EN,
+        ES,
+        ET,
+        AN,
+        CS,
+        B,
+        S,
+        WS,
+        ON,
+        AL,
+        NSM,
+        BN,
+        PDF  /* also LRE, LRO, RLE, RLO */
+    };
+
+    unsigned i;
+
+    for (i = 0; i < uCount; ++i)
+    {
+        chartype[i] = dir_map[get_char_typeW(lpString[i]) >> 12];
+        switch (chartype[i])
+        {
+        case ES:
+            if (!c->fLegacyBidiClass) break;
+            switch (lpString[i])
+            {
+            case '-':
+            case '+': chartype[i] = N; break;
+            case '/': chartype[i] = CS; break;
+            }
+            break;
+        case PDF:
+            switch (lpString[i])
+            {
+            case 0x202A: chartype[i] = LRE; break;
+            case 0x202B: chartype[i] = RLE; break;
+            case 0x202C: chartype[i] = PDF; break;
+            case 0x202D: chartype[i] = LRO; break;
+            case 0x202E: chartype[i] = RLO; break;
+            }
+            break;
+        }
+    }
+}
+
+/* Set a run of cval values at locations all prior to, but not including */
+/* iStart, to the new value nval. */
+static void SetDeferredRun(WORD *pval, int cval, int iStart, int nval)
+{
+    int i = iStart - 1;
+    for (; i >= iStart - cval; i--)
+    {
+        pval[i] = nval;
+    }
+}
+
+/* RESOLVE EXPLICIT */
+
+static WORD GreaterEven(int i)
+{
+    return odd(i) ? i + 1 : i + 2;
+}
+
+static WORD GreaterOdd(int i)
+{
+    return odd(i) ? i + 2 : i + 1;
+}
+
+static WORD EmbeddingDirection(int level)
+{
+    return odd(level) ? R : L;
+}
+
+/*------------------------------------------------------------------------
+    Function: resolveExplicit
+
+    Recursively resolves explicit embedding levels and overrides.
+    Implements rules X1-X9, of the Unicode Bidirectional Algorithm.
+
+    Input: Base embedding level and direction
+           Character count
+
+    Output: Array of embedding levels
+
+    In/Out: Array of direction classes
+
+
+    Note: The function uses two simple counters to keep track of
+          matching explicit codes and PDF. Use the default argument for
+          the outermost call. The nesting counter counts the recursion
+          depth and not the embedding level.
+------------------------------------------------------------------------*/
+
+static int resolveExplicit(int level, int dir, WORD *pcls, WORD *plevel, int cch, int nNest)
+{
+    /* always called with a valid nesting level
+       nesting levels are != embedding levels */
+    int nLastValid = nNest;
+    int ich = 0;
+
+    /* check input values */
+    ASSERT(nNest >= 0 && level >= 0 && level <= MAX_LEVEL);
+
+    /* process the text */
+    for (; ich < cch; ich++)
+    {
+        WORD cls = pcls[ich];
+        switch (cls)
+        {
+        case LRO:
+        case LRE:
+            nNest++;
+            if (GreaterEven(level) <= MAX_LEVEL - (cls == LRO ? 2 : 0))
+            {
+                plevel[ich] = GreaterEven(level);
+                pcls[ich] = BN;
+                ich += resolveExplicit(plevel[ich], (cls == LRE ? N : L),
+                            &pcls[ich+1], &plevel[ich+1],
+                             cch - (ich+1), nNest);
+                nNest--;
+                continue;
+            }
+            cls = pcls[ich] = BN;
+            break;
+
+        case RLO:
+        case RLE:
+            nNest++;
+            if (GreaterOdd(level) <= MAX_LEVEL - (cls == RLO ? 2 : 0))
+            {
+                plevel[ich] = GreaterOdd(level);
+                pcls[ich] = BN;
+                ich += resolveExplicit(plevel[ich], (cls == RLE ? N : R),
+                                &pcls[ich+1], &plevel[ich+1],
+                                 cch - (ich+1), nNest);
+                nNest--;
+                continue;
+            }
+            cls = pcls[ich] = BN;
+            break;
+
+        case PDF:
+            cls = pcls[ich] = BN;
+            if (nNest)
+            {
+                if (nLastValid < nNest)
+                {
+                    nNest--;
+                }
+                else
+                {
+                    cch = ich; /* break the loop, but complete body */
+                }
+            }
+        }
+
+        /* Apply the override */
+        if (dir != N)
+        {
+            cls = dir;
+        }
+        plevel[ich] = level;
+        if (pcls[ich] != BN)
+            pcls[ich] = cls;
+    }
+
+    return ich;
+}
+
+/* RESOLVE WEAK TYPES */
+
+enum states /* possible states */
+{
+    xa,        /*  arabic letter */
+    xr,        /*  right letter */
+    xl,        /*  left letter */
+
+    ao,        /*  arabic lett. foll by ON */
+    ro,        /*  right lett. foll by ON */
+    lo,        /*  left lett. foll by ON */
+
+    rt,        /*  ET following R */
+    lt,        /*  ET following L */
+
+    cn,        /*  EN, AN following AL */
+    ra,        /*  arabic number foll R */
+    re,        /*  european number foll R */
+    la,        /*  arabic number foll L */
+    le,        /*  european number foll L */
+
+    ac,        /*  CS following cn */
+    rc,        /*  CS following ra */
+    rs,        /*  CS,ES following re */
+    lc,        /*  CS following la */
+    ls,        /*  CS,ES following le */
+
+    ret,    /*  ET following re */
+    let,    /*  ET following le */
+} ;
+
+static const int stateWeak[][10] =
+{
+    /*    N,  L,  R, AN, EN, AL,NSM, CS, ES, ET */
+/*xa*/ { ao, xl, xr, cn, cn, xa, xa, ao, ao, ao }, /* arabic letter          */
+/*xr*/ { ro, xl, xr, ra, re, xa, xr, ro, ro, rt }, /* right letter           */
+/*xl*/ { lo, xl, xr, la, le, xa, xl, lo, lo, lt }, /* left letter            */
+
+/*ao*/ { ao, xl, xr, cn, cn, xa, ao, ao, ao, ao }, /* arabic lett. foll by ON*/
+/*ro*/ { ro, xl, xr, ra, re, xa, ro, ro, ro, rt }, /* right lett. foll by ON */
+/*lo*/ { lo, xl, xr, la, le, xa, lo, lo, lo, lt }, /* left lett. foll by ON  */
+
+/*rt*/ { ro, xl, xr, ra, re, xa, rt, ro, ro, rt }, /* ET following R         */
+/*lt*/ { lo, xl, xr, la, le, xa, lt, lo, lo, lt }, /* ET following L         */
+
+/*cn*/ { ao, xl, xr, cn, cn, xa, cn, ac, ao, ao }, /* EN, AN following AL    */
+/*ra*/ { ro, xl, xr, ra, re, xa, ra, rc, ro, rt }, /* arabic number foll R   */
+/*re*/ { ro, xl, xr, ra, re, xa, re, rs, rs,ret }, /* european number foll R */
+/*la*/ { lo, xl, xr, la, le, xa, la, lc, lo, lt }, /* arabic number foll L   */
+/*le*/ { lo, xl, xr, la, le, xa, le, ls, ls,let }, /* european number foll L */
+
+/*ac*/ { ao, xl, xr, cn, cn, xa, ao, ao, ao, ao }, /* CS following cn        */
+/*rc*/ { ro, xl, xr, ra, re, xa, ro, ro, ro, rt }, /* CS following ra        */
+/*rs*/ { ro, xl, xr, ra, re, xa, ro, ro, ro, rt }, /* CS,ES following re     */
+/*lc*/ { lo, xl, xr, la, le, xa, lo, lo, lo, lt }, /* CS following la        */
+/*ls*/ { lo, xl, xr, la, le, xa, lo, lo, lo, lt }, /* CS,ES following le     */
+
+/*ret*/{ ro, xl, xr, ra, re, xa,ret, ro, ro,ret }, /* ET following re        */
+/*let*/{ lo, xl, xr, la, le, xa,let, lo, lo,let }, /* ET following le        */
+};
+
+enum actions /* possible actions */
+{
+    /* primitives */
+    IX = 0x100,                    /* increment */
+    XX = 0xF,                    /* no-op */
+
+    /* actions */
+    xxx = (XX << 4) + XX,        /* no-op */
+    xIx = IX + xxx,                /* increment run */
+    xxN = (XX << 4) + ON,        /* set current to N */
+    xxE = (XX << 4) + EN,        /* set current to EN */
+    xxA = (XX << 4) + AN,        /* set current to AN */
+    xxR = (XX << 4) + R,        /* set current to R */
+    xxL = (XX << 4) + L,        /* set current to L */
+    Nxx = (ON << 4) + 0xF,        /* set run to neutral */
+    Axx = (AN << 4) + 0xF,        /* set run to AN */
+    ExE = (EN << 4) + EN,        /* set run to EN, set current to EN */
+    NIx = (ON << 4) + 0xF + IX, /* set run to N, increment */
+    NxN = (ON << 4) + ON,        /* set run to N, set current to N */
+    NxR = (ON << 4) + R,        /* set run to N, set current to R */
+    NxE = (ON << 4) + EN,        /* set run to N, set current to EN */
+
+    AxA = (AN << 4) + AN,        /* set run to AN, set current to AN */
+    NxL = (ON << 4) + L,        /* set run to N, set current to L */
+    LxL = (L << 4) + L,            /* set run to L, set current to L */
+}  ;
+
+static const int actionWeak[][10] =
+{
+       /*  N,   L,   R,  AN,  EN,  AL, NSM,  CS,  ES,  ET */
+/*xa*/ { xxx, xxx, xxx, xxx, xxA, xxR, xxR, xxN, xxN, xxN }, /* arabic letter           */
+/*xr*/ { xxx, xxx, xxx, xxx, xxE, xxR, xxR, xxN, xxN, xIx }, /* right letter            */
+/*xl*/ { xxx, xxx, xxx, xxx, xxL, xxR, xxL, xxN, xxN, xIx }, /* left letter             */
+
+/*ao*/ { xxx, xxx, xxx, xxx, xxA, xxR, xxN, xxN, xxN, xxN }, /* arabic lett. foll by ON */
+/*ro*/ { xxx, xxx, xxx, xxx, xxE, xxR, xxN, xxN, xxN, xIx }, /* right lett. foll by ON  */
+/*lo*/ { xxx, xxx, xxx, xxx, xxL, xxR, xxN, xxN, xxN, xIx }, /* left lett. foll by ON   */
+
+/*rt*/ { Nxx, Nxx, Nxx, Nxx, ExE, NxR, xIx, NxN, NxN, xIx }, /* ET following R         */
+/*lt*/ { Nxx, Nxx, Nxx, Nxx, LxL, NxR, xIx, NxN, NxN, xIx }, /* ET following L         */
+
+/*cn*/ { xxx, xxx, xxx, xxx, xxA, xxR, xxA, xIx, xxN, xxN }, /* EN, AN following  AL    */
+/*ra*/ { xxx, xxx, xxx, xxx, xxE, xxR, xxA, xIx, xxN, xIx }, /* arabic number foll R   */
+/*re*/ { xxx, xxx, xxx, xxx, xxE, xxR, xxE, xIx, xIx, xxE }, /* european number foll R */
+/*la*/ { xxx, xxx, xxx, xxx, xxL, xxR, xxA, xIx, xxN, xIx }, /* arabic number foll L   */
+/*le*/ { xxx, xxx, xxx, xxx, xxL, xxR, xxL, xIx, xIx, xxL }, /* european number foll L */
+
+/*ac*/ { Nxx, Nxx, Nxx, Axx, AxA, NxR, NxN, NxN, NxN, NxN }, /* CS following cn         */
+/*rc*/ { Nxx, Nxx, Nxx, Axx, NxE, NxR, NxN, NxN, NxN, NIx }, /* CS following ra         */
+/*rs*/ { Nxx, Nxx, Nxx, Nxx, ExE, NxR, NxN, NxN, NxN, NIx }, /* CS,ES following re      */
+/*lc*/ { Nxx, Nxx, Nxx, Axx, NxL, NxR, NxN, NxN, NxN, NIx }, /* CS following la         */
+/*ls*/ { Nxx, Nxx, Nxx, Nxx, LxL, NxR, NxN, NxN, NxN, NIx }, /* CS,ES following le      */
+
+/*ret*/{ xxx, xxx, xxx, xxx, xxE, xxR, xxE, xxN, xxN, xxE }, /* ET following re            */
+/*let*/{ xxx, xxx, xxx, xxx, xxL, xxR, xxL, xxN, xxN, xxL }, /* ET following le            */
+};
+
+static int GetDeferredType(int action)
+{
+    return (action >> 4) & 0xF;
+}
+
+static int GetResolvedType(int action)
+{
+    return action & 0xF;
+}
+
+/* Note on action table:
+
+  States can be of two kinds:
+     - Immediate Resolution State, where each input token
+       is resolved as soon as it is seen. These states have
+       only single action codes (xxN) or the no-op (xxx)
+       for static input tokens.
+     - Deferred Resolution State, where input tokens either
+       either extend the run (xIx) or resolve its Type (e.g. Nxx).
+
+   Input classes are of three kinds
+     - Static Input Token, where the class of the token remains
+       unchanged on output (AN, L, N, R)
+     - Replaced Input Token, where the class of the token is
+       always replaced on output (AL, BN, NSM, CS, ES, ET)
+     - Conditional Input Token, where the class of the token is
+       changed on output in some, but not all, cases (EN)
+
+     Where tokens are subject to change, a double action
+     (e.g. NxA, or NxN) is _required_ after deferred states,
+     resolving both the deferred state and changing the current token.
+*/
+
+/*------------------------------------------------------------------------
+    Function: resolveWeak
+
+    Resolves the directionality of numeric and other weak character types
+
+    Implements rules X10 and W1-W6 of the Unicode Bidirectional Algorithm.
+
+    Input: Array of embedding levels
+           Character count
+
+    In/Out: Array of directional classes
+
+    Note: On input only these directional classes are expected
+          AL, HL, R, L,  ON, BN, NSM, AN, EN, ES, ET, CS,
+------------------------------------------------------------------------*/
+static void resolveWeak(int baselevel, WORD *pcls, WORD *plevel, int cch)
+{
+    int state = odd(baselevel) ? xr : xl;
+    int cls;
+
+    int level = baselevel;
+    int action, clsRun, clsNew;
+    int cchRun = 0;
+    int ich = 0;
+
+    for (; ich < cch; ich++)
+    {
+        /* ignore boundary neutrals */
+        if (pcls[ich] == BN)
+        {
+            /* must flatten levels unless at a level change; */
+            plevel[ich] = level;
+
+            /* lookahead for level changes */
+            if (ich + 1 == cch && level != baselevel)
+            {
+                /* have to fixup last BN before end of the loop, since
+                 * its fix-upped value will be needed below the assert */
+                pcls[ich] = EmbeddingDirection(level);
+            }
+            else if (ich + 1 < cch && level != plevel[ich+1] && pcls[ich+1] != BN)
+            {
+                /* fixup LAST BN in front / after a level run to make
+                 * it act like the SOR/EOR in rule X10 */
+                int newlevel = plevel[ich+1];
+                if (level > newlevel) {
+                    newlevel = level;
+                }
+                plevel[ich] = newlevel;
+
+                /* must match assigned level */
+                pcls[ich] = EmbeddingDirection(newlevel);
+                level = plevel[ich+1];
+            }
+            else
+            {
+                /* don't interrupt runs */
+                if (cchRun)
+                {
+                    cchRun++;
+                }
+                continue;
+            }
+        }
+
+        ASSERT(pcls[ich] <= BN);
+        cls = pcls[ich];
+
+        action = actionWeak[state][cls];
+
+        /* resolve the directionality for deferred runs */
+        clsRun = GetDeferredType(action);
+        if (clsRun != XX)
+        {
+            SetDeferredRun(pcls, cchRun, ich, clsRun);
+            cchRun = 0;
+        }
+
+        /* resolve the directionality class at the current location */
+        clsNew = GetResolvedType(action);
+        if (clsNew != XX)
+            pcls[ich] = clsNew;
+
+        /* increment a deferred run */
+        if (IX & action)
+            cchRun++;
+
+        state = stateWeak[state][cls];
+    }
+
+    /* resolve any deferred runs
+     * use the direction of the current level to emulate PDF */
+    cls = EmbeddingDirection(level);
+
+    /* resolve the directionality for deferred runs */
+    clsRun = GetDeferredType(actionWeak[state][cls]);
+    if (clsRun != XX)
+        SetDeferredRun(pcls, cchRun, ich, clsRun);
+}
+
+/* RESOLVE NEUTRAL TYPES */
+
+/* action values */
+enum neutralactions
+{
+    /* action to resolve previous input */
+    nL = L,         /* resolve EN to L */
+    En = 3 << 4,    /* resolve neutrals run to embedding level direction */
+    Rn = R << 4,    /* resolve neutrals run to strong right */
+    Ln = L << 4,    /* resolved neutrals run to strong left */
+    In = (1<<8),    /* increment count of deferred neutrals */
+    LnL = (1<<4)+L, /* set run and EN to L */
+};
+
+static int GetDeferredNeutrals(int action, int level)
+{
+    action = (action >> 4) & 0xF;
+    if (action == (En >> 4))
+        return EmbeddingDirection(level);
+    else
+        return action;
+}
+
+static int GetResolvedNeutrals(int action)
+{
+    action = action & 0xF;
+    if (action == In)
+        return 0;
+    else
+        return action;
+}
+
+/* state values */
+enum resolvestates
+{
+    /* new temporary class */
+    r,  /* R and characters resolved to R */
+    l,  /* L and characters resolved to L */
+    rn, /* N preceded by right */
+    ln, /* N preceded by left */
+    a,  /* AN preceded by left (the abbreviation 'la' is used up above) */
+    na, /* N preceded by a */
+} ;
+
+
+/*------------------------------------------------------------------------
+  Notes:
+
+  By rule W7, whenever a EN is 'dominated' by an L (including start of
+  run with embedding direction = L) it is resolved to, and further treated
+  as L.
+
+  This leads to the need for 'a' and 'na' states.
+------------------------------------------------------------------------*/
+
+static const int actionNeutrals[][5] =
+{
+/*   N,  L,  R,  AN, EN = cls */
+  { In,  0,  0,  0,  0 }, /* r    right */
+  { In,  0,  0,  0,  L }, /* l    left */
+
+  { In, En, Rn, Rn, Rn }, /* rn   N preceded by right */
+  { In, Ln, En, En, LnL}, /* ln   N preceded by left */
+
+  { In,  0,  0,  0,  L }, /* a   AN preceded by left */
+  { In, En, Rn, Rn, En }, /* na   N  preceded by a */
+} ;
+
+static const int stateNeutrals[][5] =
+{
+/*   N, L,  R, AN, EN */
+  { rn, l,  r,  r,  r }, /* r   right */
+  { ln, l,  r,  a,  l }, /* l   left */
+
+  { rn, l,  r,  r,  r }, /* rn  N preceded by right */
+  { ln, l,  r,  a,  l }, /* ln  N preceded by left */
+
+  { na, l,  r,  a,  l }, /* a  AN preceded by left */
+  { na, l,  r,  a,  l }, /* na  N preceded by la */
+} ;
+
+/*------------------------------------------------------------------------
+    Function: resolveNeutrals
+
+    Resolves the directionality of neutral character types.
+
+    Implements rules W7, N1 and N2 of the Unicode Bidi Algorithm.
+
+    Input: Array of embedding levels
+           Character count
+           Baselevel
+
+    In/Out: Array of directional classes
+
+    Note: On input only these directional classes are expected
+          R,  L,  N, AN, EN and BN
+
+          W8 resolves a number of ENs to L
+------------------------------------------------------------------------*/
+static void resolveNeutrals(int baselevel, WORD *pcls, const WORD *plevel, int cch)
+{
+    /* the state at the start of text depends on the base level */
+    int state = odd(baselevel) ? r : l;
+    int cls;
+
+    int cchRun = 0;
+    int level = baselevel;
+
+    int action, clsRun, clsNew;
+    int ich = 0;
+    for (; ich < cch; ich++)
+    {
+        /* ignore boundary neutrals */
+        if (pcls[ich] == BN)
+        {
+            /* include in the count for a deferred run */
+            if (cchRun)
+                cchRun++;
+
+            /* skip any further processing */
+            continue;
+        }
+
+        ASSERT(pcls[ich] < 5); /* "Only N, L, R,  AN, EN are allowed" */
+        cls = pcls[ich];
+
+        action = actionNeutrals[state][cls];
+
+        /* resolve the directionality for deferred runs */
+        clsRun = GetDeferredNeutrals(action, level);
+        if (clsRun != N)
+        {
+            SetDeferredRun(pcls, cchRun, ich, clsRun);
+            cchRun = 0;
+        }
+
+        /* resolve the directionality class at the current location */
+        clsNew = GetResolvedNeutrals(action);
+        if (clsNew != N)
+            pcls[ich] = clsNew;
+
+        if (In & action)
+            cchRun++;
+
+        state = stateNeutrals[state][cls];
+        level = plevel[ich];
+    }
+
+    /* resolve any deferred runs */
+    cls = EmbeddingDirection(level);    /* eor has type of current level */
+
+    /* resolve the directionality for deferred runs */
+    clsRun = GetDeferredNeutrals(actionNeutrals[state][cls], level);
+    if (clsRun != N)
+        SetDeferredRun(pcls, cchRun, ich, clsRun);
+}
+
+/* RESOLVE IMPLICIT */
+
+/*------------------------------------------------------------------------
+    Function: resolveImplicit
+
+    Recursively resolves implicit embedding levels.
+    Implements rules I1 and I2 of the Unicode Bidirectional Algorithm.
+
+    Input: Array of direction classes
+           Character count
+           Base level
+
+    In/Out: Array of embedding levels
+
+    Note: levels may exceed 15 on output.
+          Accepted subset of direction classes
+          R, L, AN, EN
+------------------------------------------------------------------------*/
+static const WORD addLevel[][4] =
+{
+          /* L,  R, AN, EN */
+/* even */ { 0,  1,  2,  2, },
+/* odd  */ { 1,  0,  1,  1, }
+
+};
+
+static void resolveImplicit(const WORD * pcls, WORD *plevel, int cch)
+{
+    int ich = 0;
+    for (; ich < cch; ich++)
+    {
+        /* cannot resolve bn here, since some bn were resolved to strong
+         * types in resolveWeak. To remove these we need the original
+         * types, which are available again in resolveWhiteSpace */
+        if (pcls[ich] == BN)
+        {
+            continue;
+        }
+        ASSERT(pcls[ich] > 0); /* "No Neutrals allowed to survive here." */
+        ASSERT(pcls[ich] < 5); /* "Out of range." */
+        plevel[ich] += addLevel[odd(plevel[ich])][pcls[ich] - 1];
+    }
+}
+
+/*************************************************************
+ *    BIDI_DeterminLevels
+ */
+BOOL BIDI_DetermineLevels(
+                LPCWSTR lpString,       /* [in] The string for which information is to be returned */
+                INT uCount,     /* [in] Number of WCHARs in string. */
+                const SCRIPT_STATE *s,
+                const SCRIPT_CONTROL *c,
+                WORD *lpOutLevels /* [out] final string levels */
+    )
+{
+    WORD *chartype;
+    unsigned baselevel = 0,j;
+    TRACE("%s, %d", debugstr_wn(lpString, uCount), uCount);
+
+    chartype = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD));
+    if (!chartype)
+    {
+        WARN("Out of memory\n");
+        return FALSE;
+    }
+
+    baselevel = s->uBidiLevel;
+
+    classify(lpString, chartype, uCount, c);
+
+    for (j = 0; j < uCount; ++j)
+        switch(chartype[j])
+        {
+            case B:
+            case S:
+            case WS:
+            case ON: chartype[j] = N;
+            default: continue;
+        }
+
+    /* resolve explicit */
+    resolveExplicit(baselevel, N, chartype, lpOutLevels, uCount, 0);
+
+    /* resolve weak */
+    resolveWeak(baselevel, chartype, lpOutLevels, uCount);
+
+    /* resolve neutrals */
+    resolveNeutrals(baselevel, chartype, lpOutLevels, uCount);
+
+    /* resolveImplicit */
+    resolveImplicit(chartype, lpOutLevels, uCount);
+
+    HeapFree(GetProcessHeap(), 0, chartype);
+    return TRUE;
+}
+
+/* reverse cch indexes */
+static void reverse(int *pidx, int cch)
+{
+    int temp;
+    int ich = 0;
+    for (; ich < --cch; ich++)
+    {
+        temp = pidx[ich];
+        pidx[ich] = pidx[cch];
+        pidx[cch] = temp;
+    }
+}
+
+
+/*------------------------------------------------------------------------
+    Functions: reorder/reorderLevel
+
+    Recursively reorders the display string
+    "From the highest level down, reverse all characters at that level and
+    higher, down to the lowest odd level"
+
+    Implements rule L2 of the Unicode bidi Algorithm.
+
+    Input: Array of embedding levels
+           Character count
+           Flag enabling reversal (set to false by initial caller)
+
+    In/Out: Text to reorder
+
+    Note: levels may exceed 15 resp. 61 on input.
+
+    Rule L3 - reorder combining marks is not implemented here
+    Rule L4 - glyph mirroring is implemented as a display option below
+
+    Note: this should be applied a line at a time
+-------------------------------------------------------------------------*/
+int BIDI_ReorderV2lLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse)
+{
+    int ich = 0;
+
+    /* true as soon as first odd level encountered */
+    fReverse = fReverse || odd(level);
+
+    for (; ich < cch; ich++)
+    {
+        if (plevel[ich] < level)
+        {
+            break;
+        }
+        else if (plevel[ich] > level)
+        {
+            ich += BIDI_ReorderV2lLevel(level + 1, pIndexs + ich, plevel + ich,
+                cch - ich, fReverse) - 1;
+        }
+    }
+    if (fReverse)
+    {
+        reverse(pIndexs, ich);
+    }
+    return ich;
+}
+
+/* Applies the reorder in reverse. Taking an already reordered string and returing the original */
+int BIDI_ReorderL2vLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse)
+{
+    int ich = 0;
+    int newlevel = -1;
+
+    /* true as soon as first odd level encountered */
+    fReverse = fReverse || odd(level);
+
+    for (; ich < cch; ich++)
+    {
+        if (plevel[ich] < level)
+            break;
+        else if (plevel[ich] > level)
+            newlevel = ich;
+    }
+    if (fReverse)
+    {
+        reverse(pIndexs, ich);
+    }
+
+    if (newlevel > 1)
+    {
+        ich = 0;
+        for (; ich < cch; ich++)
+            if (plevel[ich] > level)
+                ich += BIDI_ReorderL2vLevel(level + 1, pIndexs + ich, plevel + ich,
+                cch - ich, fReverse) - 1;
+    }
+
+    return ich;
+}
index cdd6d7b..8595714 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright 2005 Steven Edwards for CodeWeavers
  * Copyright 2006 Hans Leidekker
+ * Copyright 2010 CodeWeavers, Aric Stewart
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -32,6 +33,8 @@
 #include "winnls.h"
 #include "usp10.h"
 
+#include "usp10_internal.h"
+
 #include "wine/debug.h"
 #include "wine/unicode.h"
 
@@ -524,6 +527,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
 
     int   cnt = 0, index = 0;
     int   New_Script = SCRIPT_UNDEFINED;
+    WORD  *levels = NULL;
 
     TRACE("%s,%d,%d,%p,%p,%p,%p\n", debugstr_wn(pwcInChars, cInChars), cInChars, cMaxItems, 
           psControl, psState, pItems, pcItems);
@@ -531,6 +535,24 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
     if (!pwcInChars || !cInChars || !pItems || cMaxItems < 2)
         return E_INVALIDARG;
 
+    if (psState && psControl)
+    {
+        int i;
+        levels = heap_alloc_zero(cInChars * sizeof(WORD));
+        if (!levels)
+            return E_OUTOFMEMORY;
+
+        BIDI_DetermineLevels(pwcInChars, cInChars, psState, psControl, levels);
+        for (i = 0; i < cInChars; i++)
+            if (levels[i]!=levels[0])
+                break;
+        if (i >= cInChars)
+        {
+            heap_free(levels);
+            levels = NULL;
+        }
+    }
+
     pItems[index].iCharPos = 0;
     memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
 
@@ -549,15 +571,29 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
     if  (pwcInChars[cnt] >= Latin_start && pwcInChars[cnt] <= Latin_stop)
         pItems[index].a.eScript = Script_Latin;
 
-    if  (pItems[index].a.eScript  == Script_Arabic)
+    if (levels)
+    {
+        pItems[index].a.fRTL = odd(levels[cnt]);
+        pItems[index].a.fLayoutRTL = odd(levels[cnt]);
+        pItems[index].a.s.uBidiLevel = levels[cnt];
+    }
+    else if (pItems[index].a.eScript  == Script_Arabic)
+    {
         pItems[index].a.s.uBidiLevel = 1;
+        pItems[index].a.fRTL = 1;
+        pItems[index].a.fLayoutRTL = 1;
+    }
+
 
-    TRACE("New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n",
-          New_Script, pItems[index].a.eScript, index, cnt,
+    TRACE("New_Level=%i New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n",
+          levels?levels[cnt]:-1, New_Script, pItems[index].a.eScript, index, cnt,
           pItems[index].iCharPos);
 
     for (cnt=1; cnt < cInChars; cnt++)
     {
+        if (levels && (levels[cnt] == pItems[index].a.s.uBidiLevel))
+            continue;
+
         if  (pwcInChars[cnt] == '\r')
             New_Script = Script_CR;
         else
@@ -578,9 +614,9 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
         else
             New_Script = SCRIPT_UNDEFINED;
 
-        if  (New_Script != pItems[index].a.eScript)
+        if ((levels && (levels[cnt] != pItems[index].a.s.uBidiLevel)) || New_Script != pItems[index].a.eScript)
         {
-            TRACE("New_Script=%d, eScript=%d ", New_Script, pItems[index].a.eScript);
+            TRACE("New_Level = %i, New_Script=%d, eScript=%d ", levels?levels[cnt]:-1, New_Script, pItems[index].a.eScript);
             index++;
             if  (index+1 > cMaxItems)
                 return E_OUTOFMEMORY;
@@ -588,9 +624,18 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
             pItems[index].iCharPos = cnt;
             memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
 
-            if  (New_Script == Script_Arabic)
+            if (levels)
+            {
+                pItems[index].a.fRTL = odd(levels[cnt]);
+                pItems[index].a.fLayoutRTL = odd(levels[cnt]);
+                pItems[index].a.s.uBidiLevel = levels[cnt];
+            }
+            else if  (New_Script == Script_Arabic)
+            {
                 pItems[index].a.s.uBidiLevel = 1;
-
+                pItems[index].a.fRTL = 1;
+                pItems[index].a.fLayoutRTL = 1;
+            }
             pItems[index].a.eScript = New_Script;
 
             TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos);
@@ -610,6 +655,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
     /*  Set SCRIPT_ITEM                                     */
     pItems[index+1].iCharPos = cnt;       /* the last + 1 item
                                              contains the ptr to the lastchar */
+    heap_free(levels);
     return S_OK;
 }
 
@@ -686,7 +732,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
         int numGlyphsReturned;
 
         /* FIXME: non unicode strings */
-        WCHAR* pStr = (WCHAR*)pString;
+        const WCHAR* pStr = (const WCHAR*)pString;
         hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos],
                          cChar, numGlyphs, &analysis->pItem[i].a,
                          glyphs, pwLogClust, psva, &numGlyphsReturned);
@@ -1286,6 +1332,7 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
 {
     HRESULT hr;
     unsigned int i;
+    BOOL rtl;
 
     TRACE("(%p, %p, %s, %d, %d, %p, %p, %p, %p, %p)\n", hdc, psc, debugstr_wn(pwcChars, cChars),
           cChars, cMaxGlyphs, psa, pwOutGlyphs, pwLogClust, psva, pcGlyphs);
@@ -1295,6 +1342,7 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
 
     if (!psva || !pcGlyphs) return E_INVALIDARG;
     if (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
+    rtl = (!psa->fLogicalOrder && psa->fRTL);
 
     *pcGlyphs = cChars;
     if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
@@ -1304,33 +1352,42 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
     {
         for (i = 0; i < cChars; i++)
         {
-            if (!(pwOutGlyphs[i] = get_cache_glyph(psc, pwcChars[i])))
+            int idx = i;
+            if (rtl) idx = cChars - 1 - i;
+            if (!(pwOutGlyphs[i] = get_cache_glyph(psc, pwcChars[idx])))
             {
                 WORD glyph;
                 if (!hdc) return E_PENDING;
-                if (GetGlyphIndicesW(hdc, &pwcChars[i], 1, &glyph, 0) == GDI_ERROR) return S_FALSE;
-                pwOutGlyphs[i] = set_cache_glyph(psc, pwcChars[i], glyph);
+                if (GetGlyphIndicesW(hdc, &pwcChars[idx], 1, &glyph, 0) == GDI_ERROR) return S_FALSE;
+                pwOutGlyphs[i] = set_cache_glyph(psc, pwcChars[idx], glyph);
             }
         }
     }
     else
     {
         TRACE("no glyph translation\n");
-        for (i = 0; i < cChars; i++) pwOutGlyphs[i] = pwcChars[i];
+        for (i = 0; i < cChars; i++)
+        {
+            int idx = i;
+            if (rtl) idx = cChars - 1 - i;
+            pwOutGlyphs[i] = pwcChars[idx];
+        }
     }
 
     /* set up a valid SCRIPT_VISATTR and LogClust for each char in this run */
     for (i = 0; i < cChars; i++)
     {
+        int idx = i;
+        if (rtl) idx = cChars - 1 - i;
         /* FIXME: set to better values */
-        psva[i].uJustification = (pwcChars[i] == ' ') ? SCRIPT_JUSTIFY_BLANK : SCRIPT_JUSTIFY_CHARACTER;
+        psva[i].uJustification = (pwcChars[idx] == ' ') ? SCRIPT_JUSTIFY_BLANK : SCRIPT_JUSTIFY_CHARACTER;
         psva[i].fClusterStart  = 1;
         psva[i].fDiacritic     = 0;
         psva[i].fZeroWidth     = 0;
         psva[i].fReserved      = 0;
         psva[i].fShapeReserved = 0;
 
-        pwLogClust[i] = i;
+        pwLogClust[i] = idx;
     }
     return S_OK;
 }
@@ -1573,28 +1630,45 @@ HRESULT WINAPI ScriptGetGlyphABCWidth(HDC hdc, SCRIPT_CACHE *psc, WORD glyph, AB
  */
 HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *logtovis)
 {
-    int i, j = runs - 1, k = 0;
+    int* indexs;
+    int ich;
 
     TRACE("(%d, %p, %p, %p)\n", runs, level, vistolog, logtovis);
 
     if (!level || (!vistolog && !logtovis))
         return E_INVALIDARG;
 
-    for (i = 0; i < runs; i++)
+    indexs = heap_alloc(sizeof(int) * runs);
+    if (!indexs)
+        return E_OUTOFMEMORY;
+
+
+    if (vistolog)
     {
-        if (level[i] % 2)
-        {
-            if (vistolog) *vistolog++ = j;
-            if (logtovis) *logtovis++ = j;
-            j--;
-        }
-        else
-        {
-            if (vistolog) *vistolog++ = k;
-            if (logtovis) *logtovis++ = k;
-            k++;
-        }
+        for( ich = 0; ich < runs; ich++)
+            indexs[ich] = ich;
+
+        ich = 0;
+        while (ich < runs)
+            ich += BIDI_ReorderV2lLevel(0, indexs+ich, level+ich, runs - ich, FALSE);
+        for (ich = 0; ich < runs; ich++)
+            vistolog[ich] = indexs[ich];
     }
+
+
+    if (logtovis)
+    {
+        for( ich = 0; ich < runs; ich++)
+            indexs[ich] = ich;
+
+        ich = 0;
+        while (ich < runs)
+            ich += BIDI_ReorderL2vLevel(0, indexs+ich, level+ich, runs - ich, FALSE);
+        for (ich = 0; ich < runs; ich++)
+            logtovis[ich] = indexs[ich];
+    }
+    heap_free(indexs);
+
     return S_OK;
 }
 
@@ -1839,9 +1913,3 @@ HRESULT WINAPI ScriptJustify(const SCRIPT_VISATTR *sva, const int *advance,
     for (i = 0; i < num_glyphs; i++) justify[i] = advance[i];
     return S_OK;
 }
-
-BOOL gbLpkPresent = FALSE;
-VOID WINAPI LpkPresent()
-{
-    gbLpkPresent = TRUE; /* Turn it on this way! Wine is out of control! */
-}
index ad07101..527578c 100644 (file)
@@ -6,6 +6,7 @@
        <include base="usp10">.</include>
        <include base="ReactOS">include/reactos/wine</include>
        <define name="__WINESRC__" />
+       <file>bidi.c</file>
        <file>usp10.c</file>
        <library>wine</library>
        <library>gdi32</library>
index 0f7b0aa..5e35870 100644 (file)
@@ -1,4 +1,4 @@
-@ stdcall LpkPresent()
+@ stub LpkPresent
 @ stdcall ScriptApplyDigitSubstitution(ptr ptr ptr)
 @ stdcall ScriptApplyLogicalWidth(ptr long long ptr ptr ptr ptr ptr ptr)
 @ stdcall ScriptBreak(ptr long ptr ptr)
diff --git a/dll/win32/usp10/usp10_internal.h b/dll/win32/usp10/usp10_internal.h
new file mode 100644 (file)
index 0000000..60e4eff
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Implementation of Uniscribe Script Processor (usp10.dll)
+ *
+ * Copyright 2010 CodeWeavers, Aric Stewart
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+#define odd(x) ((x) & 1)
+
+BOOL BIDI_DetermineLevels( LPCWSTR lpString, INT uCount, const SCRIPT_STATE *s,
+                const SCRIPT_CONTROL *c, WORD *lpOutLevels );
+
+INT BIDI_ReorderV2lLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse);
+INT BIDI_ReorderL2vLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse);
index e7d34e0..16d9eac 100644 (file)
@@ -199,7 +199,11 @@ static BOOL find_ne_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff )
  */
 static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff )
 {
-    IMAGE_NT_HEADERS pehd;
+    union
+    {
+        IMAGE_NT_HEADERS32 nt32;
+        IMAGE_NT_HEADERS64 nt64;
+    } pehd;
     DWORD pehdoffset;
     PIMAGE_DATA_DIRECTORY resDataDir;
     PIMAGE_SECTION_HEADER sections;
@@ -208,14 +212,27 @@ static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff )
     const void *resDir;
     const IMAGE_RESOURCE_DIRECTORY *resPtr;
     const IMAGE_RESOURCE_DATA_ENTRY *resData;
-    int i, nSections;
+    int i, len, nSections;
     BOOL ret = FALSE;
 
     /* Read in PE header */
     pehdoffset = LZSeek( lzfd, 0, SEEK_CUR );
-    if ( sizeof(pehd) != LZRead( lzfd, (LPSTR)&pehd, sizeof(pehd) ) ) return 0;
+    len = LZRead( lzfd, (LPSTR)&pehd, sizeof(pehd) );
+    if (len < sizeof(pehd.nt32.FileHeader)) return 0;
+    if (len < sizeof(pehd)) memset( (char *)&pehd + len, 0, sizeof(pehd) - len );
+
+    switch (pehd.nt32.OptionalHeader.Magic)
+    {
+    case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+        resDataDir = pehd.nt32.OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_RESOURCE;
+        break;
+    case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+        resDataDir = pehd.nt64.OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_RESOURCE;
+        break;
+    default:
+        return 0;
+    }
 
-    resDataDir = pehd.OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
     if ( !resDataDir->Size )
     {
         TRACE("No resources in PE dll\n" );
@@ -223,15 +240,13 @@ static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff )
     }
 
     /* Read in section table */
-    nSections = pehd.FileHeader.NumberOfSections;
+    nSections = pehd.nt32.FileHeader.NumberOfSections;
     sections = HeapAlloc( GetProcessHeap(), 0,
                           nSections * sizeof(IMAGE_SECTION_HEADER) );
     if ( !sections ) return FALSE;
 
-    LZSeek( lzfd, pehdoffset +
-                    sizeof(DWORD) + /* Signature */
-                    sizeof(IMAGE_FILE_HEADER) +
-                    pehd.FileHeader.SizeOfOptionalHeader, SEEK_SET );
+    len = FIELD_OFFSET( IMAGE_NT_HEADERS32, OptionalHeader ) + pehd.nt32.FileHeader.SizeOfOptionalHeader;
+    LZSeek( lzfd, pehdoffset + len, SEEK_SET );
 
     if ( nSections * sizeof(IMAGE_SECTION_HEADER) !=
          LZRead( lzfd, (LPSTR)sections, nSections * sizeof(IMAGE_SECTION_HEADER) ) )
index 5c805c8..854b337 100644 (file)
@@ -58,12 +58,14 @@ typedef struct {
     DWORD bc2AppData;
 } BITMAPCOREHEADER2;
 
-struct BmpFrameDecode;
-typedef HRESULT (*ReadDataFunc)(struct BmpFrameDecode* This);
+struct BmpDecoder;
+typedef HRESULT (*ReadDataFunc)(struct BmpDecoder* This);
 
-typedef struct BmpFrameDecode {
-    const IWICBitmapFrameDecodeVtbl *lpVtbl;
+typedef struct BmpDecoder {
+    const IWICBitmapDecoderVtbl *lpVtbl;
+    const IWICBitmapFrameDecodeVtbl *lpFrameVtbl;
     LONG ref;
+    BOOL initialized;
     IStream *stream;
     BITMAPFILEHEADER bfh;
     BITMAPV5HEADER bih;
@@ -73,12 +75,17 @@ typedef struct BmpFrameDecode {
     INT stride;
     BYTE *imagedata;
     BYTE *imagedatastart;
-} BmpFrameDecode;
+    CRITICAL_SECTION lock; /* must be held when initialized/imagedata is set or stream is accessed */
+} BmpDecoder;
+
+static inline BmpDecoder *impl_from_frame(IWICBitmapFrameDecode *iface)
+{
+    return CONTAINING_RECORD(iface, BmpDecoder, lpFrameVtbl);
+}
 
 static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
     void **ppv)
 {
-    BmpFrameDecode *This = (BmpFrameDecode*)iface;
     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
 
     if (!ppv) return E_INVALIDARG;
@@ -87,7 +94,7 @@ static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface
         IsEqualIID(&IID_IWICBitmapSource, iid) ||
         IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
     {
-        *ppv = This;
+        *ppv = iface;
     }
     else
     {
@@ -101,35 +108,22 @@ static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface
 
 static ULONG WINAPI BmpFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
 {
-    BmpFrameDecode *This = (BmpFrameDecode*)iface;
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p) refcount=%u\n", iface, ref);
+    BmpDecoder *This = impl_from_frame(iface);
 
-    return ref;
+    return IUnknown_AddRef((IUnknown*)This);
 }
 
 static ULONG WINAPI BmpFrameDecode_Release(IWICBitmapFrameDecode *iface)
 {
-    BmpFrameDecode *This = (BmpFrameDecode*)iface;
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p) refcount=%u\n", iface, ref);
-
-    if (ref == 0)
-    {
-        IStream_Release(This->stream);
-        HeapFree(GetProcessHeap(), 0, This->imagedata);
-        HeapFree(GetProcessHeap(), 0, This);
-    }
+    BmpDecoder *This = impl_from_frame(iface);
 
-    return ref;
+    return IUnknown_Release((IUnknown*)This);
 }
 
 static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
     UINT *puiWidth, UINT *puiHeight)
 {
-    BmpFrameDecode *This = (BmpFrameDecode*)iface;
+    BmpDecoder *This = impl_from_frame(iface);
     TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
 
     if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
@@ -149,7 +143,7 @@ static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
 static HRESULT WINAPI BmpFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface,
     WICPixelFormatGUID *pPixelFormat)
 {
-    BmpFrameDecode *This = (BmpFrameDecode*)iface;
+    BmpDecoder *This = impl_from_frame(iface);
     TRACE("(%p,%p)\n", iface, pPixelFormat);
 
     memcpy(pPixelFormat, This->pixelformat, sizeof(GUID));
@@ -180,7 +174,7 @@ static HRESULT BmpHeader_GetResolution(BITMAPV5HEADER *bih, double *pDpiX, doubl
 static HRESULT WINAPI BmpFrameDecode_GetResolution(IWICBitmapFrameDecode *iface,
     double *pDpiX, double *pDpiY)
 {
-    BmpFrameDecode *This = (BmpFrameDecode*)iface;
+    BmpDecoder *This = impl_from_frame(iface);
     TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
 
     return BmpHeader_GetResolution(&This->bih, pDpiX, pDpiY);
@@ -190,13 +184,15 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
     IWICPalette *pIPalette)
 {
     HRESULT hr;
-    BmpFrameDecode *This = (BmpFrameDecode*)iface;
+    BmpDecoder *This = impl_from_frame(iface);
     int count;
     WICColor *wiccolors=NULL;
     RGBTRIPLE *bgrcolors=NULL;
 
     TRACE("(%p,%p)\n", iface, pIPalette);
 
+    EnterCriticalSection(&This->lock);
+
     if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
     {
         BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
@@ -238,7 +234,8 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
         }
         else
         {
-            return WINCODEC_ERR_PALETTEUNAVAILABLE;
+            hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
+            goto end;
         }
     }
     else
@@ -256,7 +253,11 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
 
             tablesize = sizeof(WICColor) * count;
             wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize);
-            if (!wiccolors) return E_OUTOFMEMORY;
+            if (!wiccolors)
+            {
+                hr = E_OUTOFMEMORY;
+                goto end;
+            }
 
             offset.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size;
             hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL);
@@ -275,13 +276,18 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
         }
         else
         {
-            return WINCODEC_ERR_PALETTEUNAVAILABLE;
+            hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
+            goto end;
         }
     }
 
-    hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count);
-
 end:
+
+    LeaveCriticalSection(&This->lock);
+
+    if (SUCCEEDED(hr))
+        hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count);
+
     HeapFree(GetProcessHeap(), 0, wiccolors);
     HeapFree(GetProcessHeap(), 0, bgrcolors);
     return hr;
@@ -290,16 +296,18 @@ end:
 static HRESULT WINAPI BmpFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
     const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
 {
-    BmpFrameDecode *This = (BmpFrameDecode*)iface;
-    HRESULT hr;
+    BmpDecoder *This = impl_from_frame(iface);
+    HRESULT hr=S_OK;
     UINT width, height;
     TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
 
+    EnterCriticalSection(&This->lock);
     if (!This->imagedata)
     {
         hr = This->read_data_func(This);
-        if (FAILED(hr)) return hr;
     }
+    LeaveCriticalSection(&This->lock);
+    if (FAILED(hr)) return hr;
 
     hr = BmpFrameDecode_GetSize(iface, &width, &height);
     if (FAILED(hr)) return hr;
@@ -330,7 +338,7 @@ static HRESULT WINAPI BmpFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface,
     return WINCODEC_ERR_CODECNOTHUMBNAIL;
 }
 
-static HRESULT BmpFrameDecode_ReadUncompressed(BmpFrameDecode* This)
+static HRESULT BmpFrameDecode_ReadUncompressed(BmpDecoder* This)
 {
     UINT bytesperrow;
     UINT width, height;
@@ -387,7 +395,7 @@ fail:
     return hr;
 }
 
-static HRESULT BmpFrameDecode_ReadRLE8(BmpFrameDecode* This)
+static HRESULT BmpFrameDecode_ReadRLE8(BmpDecoder* This)
 {
     UINT bytesperrow;
     UINT width, height;
@@ -493,7 +501,7 @@ fail:
     return hr;
 }
 
-static HRESULT BmpFrameDecode_ReadRLE4(BmpFrameDecode* This)
+static HRESULT BmpFrameDecode_ReadRLE4(BmpDecoder* This)
 {
     UINT bytesperrow;
     UINT width, height;
@@ -614,7 +622,7 @@ fail:
     return hr;
 }
 
-static HRESULT BmpFrameDecode_ReadUnsupported(BmpFrameDecode* This)
+static HRESULT BmpFrameDecode_ReadUnsupported(BmpDecoder* This)
 {
     return E_FAIL;
 }
@@ -637,7 +645,7 @@ static const struct bitfields_format bitfields_formats[] = {
     {0}
 };
 
-static const IWICBitmapFrameDecodeVtbl BmpFrameDecode_Vtbl = {
+static const IWICBitmapFrameDecodeVtbl BmpDecoder_FrameVtbl = {
     BmpFrameDecode_QueryInterface,
     BmpFrameDecode_AddRef,
     BmpFrameDecode_Release,
@@ -651,19 +659,6 @@ static const IWICBitmapFrameDecodeVtbl BmpFrameDecode_Vtbl = {
     BmpFrameDecode_GetThumbnail
 };
 
-typedef struct {
-    const IWICBitmapDecoderVtbl *lpVtbl;
-    LONG ref;
-    BOOL initialized;
-    IStream *stream;
-    BITMAPFILEHEADER bfh;
-    BITMAPV5HEADER bih;
-    BmpFrameDecode *framedecode;
-    const WICPixelFormatGUID *pixelformat;
-    int bitsperpixel;
-    ReadDataFunc read_data_func;
-} BmpDecoder;
-
 static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream)
 {
     HRESULT hr;
@@ -873,7 +868,9 @@ static ULONG WINAPI BmpDecoder_Release(IWICBitmapDecoder *iface)
     if (ref == 0)
     {
         if (This->stream) IStream_Release(This->stream);
-        if (This->framedecode) IUnknown_Release((IUnknown*)This->framedecode);
+        HeapFree(GetProcessHeap(), 0, This->imagedata);
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -886,7 +883,9 @@ static HRESULT WINAPI BmpDecoder_QueryCapability(IWICBitmapDecoder *iface, IStre
     HRESULT hr;
     BmpDecoder *This = (BmpDecoder*)iface;
 
+    EnterCriticalSection(&This->lock);
     hr = BmpDecoder_ReadHeaders(This, pIStream);
+    LeaveCriticalSection(&This->lock);
     if (FAILED(hr)) return hr;
 
     if (This->read_data_func == BmpFrameDecode_ReadUnsupported)
@@ -903,6 +902,7 @@ static HRESULT WINAPI BmpDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
     HRESULT hr;
     BmpDecoder *This = (BmpDecoder*)iface;
 
+    EnterCriticalSection(&This->lock);
     hr = BmpDecoder_ReadHeaders(This, pIStream);
 
     if (SUCCEEDED(hr))
@@ -910,6 +910,7 @@ static HRESULT WINAPI BmpDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
         This->stream = pIStream;
         IStream_AddRef(pIStream);
     }
+    LeaveCriticalSection(&This->lock);
 
     return hr;
 }
@@ -992,25 +993,8 @@ static HRESULT WINAPI BmpDecoder_GetFrame(IWICBitmapDecoder *iface,
 
     if (!This->stream) return WINCODEC_ERR_WRONGSTATE;
 
-    if (!This->framedecode)
-    {
-        This->framedecode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameDecode));
-        if (!This->framedecode) return E_OUTOFMEMORY;
-
-        This->framedecode->lpVtbl = &BmpFrameDecode_Vtbl;
-        This->framedecode->ref = 1;
-        This->framedecode->stream = This->stream;
-        IStream_AddRef(This->stream);
-        This->framedecode->bfh = This->bfh;
-        This->framedecode->bih = This->bih;
-        This->framedecode->pixelformat = This->pixelformat;
-        This->framedecode->bitsperpixel = This->bitsperpixel;
-        This->framedecode->read_data_func = This->read_data_func;
-        This->framedecode->imagedata = NULL;
-    }
-
-    *ppIBitmapFrame = (IWICBitmapFrameDecode*)This->framedecode;
-    IWICBitmapFrameDecode_AddRef((IWICBitmapFrameDecode*)This->framedecode);
+    *ppIBitmapFrame = (IWICBitmapFrameDecode*)&This->lpFrameVtbl;
+    IWICBitmapDecoder_AddRef(iface);
 
     return S_OK;
 }
@@ -1047,10 +1031,13 @@ HRESULT BmpDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
     if (!This) return E_OUTOFMEMORY;
 
     This->lpVtbl = &BmpDecoder_Vtbl;
+    This->lpFrameVtbl = &BmpDecoder_FrameVtbl;
     This->ref = 1;
     This->initialized = FALSE;
     This->stream = NULL;
-    This->framedecode = NULL;
+    This->imagedata = NULL;
+    InitializeCriticalSection(&This->lock);
+    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BmpDecoder.lock");
 
     ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
     IUnknown_Release((IUnknown*)This);
index d8d2105..68e0530 100644 (file)
@@ -50,6 +50,7 @@ static classinfo wic_classes[] = {
     {&CLSID_WICGifDecoder, GifDecoder_CreateInstance},
     {&CLSID_WICIcoDecoder, IcoDecoder_CreateInstance},
     {&CLSID_WICJpegDecoder, JpegDecoder_CreateInstance},
+    {&CLSID_WICTiffDecoder, TiffDecoder_CreateInstance},
     {&CLSID_WICDefaultFormatConverter, FormatConverter_CreateInstance},
     {0}};
 
index 15c7b0f..b1c0952 100644 (file)
@@ -71,6 +71,7 @@ typedef struct FormatConverter {
     WICBitmapDitherType dither;
     double alpha_threshold;
     WICBitmapPaletteType palette_type;
+    CRITICAL_SECTION lock; /* must be held when initialized */
 } FormatConverter;
 
 static void make_grayscale_palette(WICColor *colors, UINT num_colors)
@@ -765,6 +766,8 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
 
     if (ref == 0)
     {
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
         if (This->source) IWICBitmapSource_Release(This->source);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -841,38 +844,56 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
     const struct pixelformatinfo *srcinfo, *dstinfo;
     static INT fixme=0;
     GUID srcFormat;
-    HRESULT res;
+    HRESULT res=S_OK;
 
     TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat),
         dither, pIPalette, alphaThresholdPercent, paletteTranslate);
 
     if (pIPalette && !fixme++) FIXME("ignoring palette\n");
 
-    if (This->source) return WINCODEC_ERR_WRONGSTATE;
+    EnterCriticalSection(&This->lock);
+
+    if (This->source)
+    {
+        res = WINCODEC_ERR_WRONGSTATE;
+        goto end;
+    }
 
     res = IWICBitmapSource_GetPixelFormat(pISource, &srcFormat);
-    if (FAILED(res)) return res;
+    if (FAILED(res)) goto end;
 
     srcinfo = get_formatinfo(&srcFormat);
-    if (!srcinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+    if (!srcinfo)
+    {
+        res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+        goto end;
+    }
 
     dstinfo = get_formatinfo(dstFormat);
-    if (!dstinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+    if (!dstinfo)
+    {
+        res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+        goto end;
+    }
 
     if (dstinfo->copy_function)
     {
         IWICBitmapSource_AddRef(pISource);
-        This->source = pISource;
         This->src_format = srcinfo;
         This->dst_format = dstinfo;
         This->dither = dither;
         This->alpha_threshold = alphaThresholdPercent;
         This->palette_type = paletteTranslate;
+        This->source = pISource;
     }
     else
-        return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+        res = WINCODEC_ERR_UNSUPPORTEDOPERATION;
 
-    return S_OK;
+end:
+
+    LeaveCriticalSection(&This->lock);
+
+    return res;
 }
 
 static HRESULT WINAPI FormatConverter_CanConvert(IWICFormatConverter *iface,
@@ -930,6 +951,8 @@ HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** p
     This->lpVtbl = &FormatConverter_Vtbl;
     This->ref = 1;
     This->source = NULL;
+    InitializeCriticalSection(&This->lock);
+    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock");
 
     ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
     IUnknown_Release((IUnknown*)This);
index 0597b1a..3443b2c 100644 (file)
@@ -40,6 +40,7 @@ typedef struct {
     LONG ref;
     BOOL initialized;
     GifFileType *gif;
+    CRITICAL_SECTION lock;
 } GifDecoder;
 
 typedef struct {
@@ -302,6 +303,8 @@ static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface)
 
     if (ref == 0)
     {
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
         DGifCloseFile(This->gif);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -341,9 +344,12 @@ static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
 
     TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
 
+    EnterCriticalSection(&This->lock);
+
     if (This->initialized || This->gif)
     {
         WARN("already initialized\n");
+        LeaveCriticalSection(&This->lock);
         return WINCODEC_ERR_WRONGSTATE;
     }
 
@@ -353,16 +359,26 @@ static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
 
     /* read all data from the stream */
     This->gif = DGifOpen((void*)pIStream, _gif_inputfunc);
-    if (!This->gif) return E_FAIL;
+    if (!This->gif)
+    {
+        LeaveCriticalSection(&This->lock);
+        return E_FAIL;
+    }
 
     ret = DGifSlurp(This->gif);
-    if (ret == GIF_ERROR) return E_FAIL;
+    if (ret == GIF_ERROR)
+    {
+        LeaveCriticalSection(&This->lock);
+        return E_FAIL;
+    }
 
     /* make sure we don't use the stream after this method returns */
     This->gif->UserData = NULL;
 
     This->initialized = TRUE;
 
+    LeaveCriticalSection(&This->lock);
+
     return S_OK;
 }
 
@@ -502,6 +518,8 @@ HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
     This->ref = 1;
     This->initialized = FALSE;
     This->gif = NULL;
+    InitializeCriticalSection(&This->lock);
+    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": GifDecoder.lock");
 
     ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
     IUnknown_Release((IUnknown*)This);
index ab30ab0..e1ea7c6 100644 (file)
@@ -62,6 +62,7 @@ typedef struct {
     BOOL initialized;
     IStream *stream;
     ICONHEADER header;
+    CRITICAL_SECTION lock; /* must be held when accessing stream */
 } IcoDecoder;
 
 typedef struct {
@@ -512,15 +513,17 @@ static HRESULT WINAPI IcoFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
     const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
 {
     IcoFrameDecode *This = (IcoFrameDecode*)iface;
-    HRESULT hr;
+    HRESULT hr=S_OK;
     UINT width, height, stride;
     TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
 
+    EnterCriticalSection(&This->parent->lock);
     if (!This->bits)
     {
         hr = IcoFrameDecode_ReadPixels(This);
-        if (FAILED(hr)) return hr;
     }
+    LeaveCriticalSection(&This->parent->lock);
+    if (FAILED(hr)) return hr;
 
     width = This->entry.bWidth ? This->entry.bWidth : 256;
     height = This->entry.bHeight ? This->entry.bHeight : 256;
@@ -606,6 +609,8 @@ static ULONG WINAPI IcoDecoder_Release(IWICBitmapDecoder *iface)
 
     if (ref == 0)
     {
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
         if (This->stream) IStream_Release(This->stream);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -629,23 +634,37 @@ static HRESULT WINAPI IcoDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
     ULONG bytesread;
     TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
 
-    if (This->initialized) return WINCODEC_ERR_WRONGSTATE;
+    EnterCriticalSection(&This->lock);
+
+    if (This->initialized)
+    {
+        hr = WINCODEC_ERR_WRONGSTATE;
+        goto end;
+    }
 
     seek.QuadPart = 0;
     hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
-    if (FAILED(hr)) return hr;
+    if (FAILED(hr)) goto end;
 
     hr = IStream_Read(pIStream, &This->header, sizeof(ICONHEADER), &bytesread);
-    if (FAILED(hr)) return hr;
+    if (FAILED(hr)) goto end;
     if (bytesread != sizeof(ICONHEADER) ||
         This->header.idReserved != 0 ||
-        This->header.idType != 1) return E_FAIL;
+        This->header.idType != 1)
+    {
+        hr = E_FAIL;
+        goto end;
+    }
 
     This->initialized = TRUE;
     This->stream = pIStream;
     IStream_AddRef(pIStream);
 
-    return S_OK;
+end:
+
+    LeaveCriticalSection(&This->lock);
+
+    return hr;
 }
 
 static HRESULT WINAPI IcoDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
@@ -715,18 +734,32 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
     UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
 {
     IcoDecoder *This = (IcoDecoder*)iface;
-    IcoFrameDecode *result;
+    IcoFrameDecode *result=NULL;
     LARGE_INTEGER seek;
     HRESULT hr;
     ULONG bytesread;
     TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
 
-    if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED;
+    EnterCriticalSection(&This->lock);
+
+    if (!This->initialized)
+    {
+        hr = WINCODEC_ERR_NOTINITIALIZED;
+        goto fail;
+    }
 
-    if (This->header.idCount < index) return E_INVALIDARG;
+    if (This->header.idCount < index)
+    {
+        hr = E_INVALIDARG;
+        goto fail;
+    }
 
     result = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoFrameDecode));
-    if (!result) return E_OUTOFMEMORY;
+    if (!result)
+    {
+        hr = E_OUTOFMEMORY;
+        goto fail;
+    }
 
     result->lpVtbl = &IcoFrameDecode_Vtbl;
     result->ref = 1;
@@ -745,9 +778,12 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
 
     *ppIBitmapFrame = (IWICBitmapFrameDecode*)result;
 
+    LeaveCriticalSection(&This->lock);
+
     return S_OK;
 
 fail:
+    LeaveCriticalSection(&This->lock);
     HeapFree(GetProcessHeap(), 0, result);
     if (SUCCEEDED(hr)) hr = E_FAIL;
     TRACE("<-- %x\n", hr);
@@ -789,6 +825,8 @@ HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
     This->ref = 1;
     This->stream = NULL;
     This->initialized = FALSE;
+    InitializeCriticalSection(&This->lock);
+    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcoDecoder.lock");
 
     ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
     IUnknown_Release((IUnknown*)This);
index 017e604..b5676ea 100644 (file)
@@ -103,6 +103,7 @@ typedef struct {
     struct jpeg_source_mgr source_mgr;
     BYTE source_buffer[1024];
     BYTE *image_data;
+    CRITICAL_SECTION lock;
 } JpegDecoder;
 
 static inline JpegDecoder *decoder_from_decompress(j_decompress_ptr decompress)
@@ -156,6 +157,8 @@ static ULONG WINAPI JpegDecoder_Release(IWICBitmapDecoder *iface)
 
     if (ref == 0)
     {
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
         if (This->cinfo_initialized) pjpeg_destroy_decompress(&This->cinfo);
         if (This->stream) IStream_Release(This->stream);
         HeapFree(GetProcessHeap(), 0, This->image_data);
@@ -225,7 +228,13 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream *
     int ret;
     TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions);
 
-    if (This->cinfo_initialized) return WINCODEC_ERR_WRONGSTATE;
+    EnterCriticalSection(&This->lock);
+
+    if (This->cinfo_initialized)
+    {
+        LeaveCriticalSection(&This->lock);
+        return WINCODEC_ERR_WRONGSTATE;
+    }
 
     This->cinfo.err = pjpeg_std_error(&This->jerr);
 
@@ -249,6 +258,7 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream *
 
     if (ret != JPEG_HEADER_OK) {
         WARN("Jpeg image in stream has bad format, read header returned %d.\n",ret);
+        LeaveCriticalSection(&This->lock);
         return E_FAIL;
     }
 
@@ -260,11 +270,14 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream *
     if (!pjpeg_start_decompress(&This->cinfo))
     {
         ERR("jpeg_start_decompress failed\n");
+        LeaveCriticalSection(&This->lock);
         return E_FAIL;
     }
 
     This->initialized = TRUE;
 
+    LeaveCriticalSection(&This->lock);
+
     return S_OK;
 }
 
@@ -448,10 +461,16 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
     max_row_needed = prc->Y + prc->Height;
     if (max_row_needed > This->cinfo.output_height) return E_INVALIDARG;
 
+    EnterCriticalSection(&This->lock);
+
     if (!This->image_data)
     {
         This->image_data = HeapAlloc(GetProcessHeap(), 0, data_size);
-        if (!This->image_data) return E_OUTOFMEMORY;
+        if (!This->image_data)
+        {
+            LeaveCriticalSection(&This->lock);
+            return E_OUTOFMEMORY;
+        }
     }
 
     while (max_row_needed > This->cinfo.output_scanline)
@@ -471,6 +490,7 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
         if (ret == 0)
         {
             ERR("read_scanlines failed\n");
+            LeaveCriticalSection(&This->lock);
             return E_FAIL;
         }
 
@@ -492,6 +512,8 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
         }
     }
 
+    LeaveCriticalSection(&This->lock);
+
     return copy_pixels(bpp, This->image_data,
         This->cinfo.output_width, This->cinfo.output_height, stride,
         prc, cbStride, cbBufferSize, pbBuffer);
@@ -559,6 +581,8 @@ HRESULT JpegDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
     This->cinfo_initialized = FALSE;
     This->stream = NULL;
     This->image_data = NULL;
+    InitializeCriticalSection(&This->lock);
+    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JpegDecoder.lock");
 
     ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
     IUnknown_Release((IUnknown*)This);
index 842d3b5..40ab190 100644 (file)
@@ -40,6 +40,7 @@ typedef struct {
     UINT count;
     WICColor *colors;
     WICBitmapPaletteType type;
+    CRITICAL_SECTION lock; /* must be held when count, colors, or type is accessed */
 } PaletteImpl;
 
 static HRESULT WINAPI PaletteImpl_QueryInterface(IWICPalette *iface, REFIID iid,
@@ -83,6 +84,8 @@ static ULONG WINAPI PaletteImpl_Release(IWICPalette *iface)
 
     if (ref == 0)
     {
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
         HeapFree(GetProcessHeap(), 0, This->colors);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -117,10 +120,12 @@ static HRESULT WINAPI PaletteImpl_InitializeCustom(IWICPalette *iface,
         memcpy(new_colors, pColors, sizeof(WICColor) * colorCount);
     }
 
+    EnterCriticalSection(&This->lock);
     HeapFree(GetProcessHeap(), 0, This->colors);
     This->colors = new_colors;
     This->count = colorCount;
     This->type = WICBitmapPaletteTypeCustom;
+    LeaveCriticalSection(&This->lock);
 
     return S_OK;
 }
@@ -148,7 +153,9 @@ static HRESULT WINAPI PaletteImpl_GetType(IWICPalette *iface,
 
     if (!pePaletteType) return E_INVALIDARG;
 
+    EnterCriticalSection(&This->lock);
     *pePaletteType = This->type;
+    LeaveCriticalSection(&This->lock);
 
     return S_OK;
 }
@@ -161,7 +168,9 @@ static HRESULT WINAPI PaletteImpl_GetColorCount(IWICPalette *iface, UINT *pcCoun
 
     if (!pcCount) return E_INVALIDARG;
 
+    EnterCriticalSection(&This->lock);
     *pcCount = This->count;
+    LeaveCriticalSection(&This->lock);
 
     return S_OK;
 }
@@ -175,12 +184,16 @@ static HRESULT WINAPI PaletteImpl_GetColors(IWICPalette *iface, UINT colorCount,
 
     if (!pColors || !pcActualColors) return E_INVALIDARG;
 
+    EnterCriticalSection(&This->lock);
+
     if (This->count < colorCount) colorCount = This->count;
 
     memcpy(pColors, This->colors, sizeof(WICColor) * colorCount);
 
     *pcActualColors = colorCount;
 
+    LeaveCriticalSection(&This->lock);
+
     return S_OK;
 }
 
@@ -192,10 +205,12 @@ static HRESULT WINAPI PaletteImpl_IsBlackWhite(IWICPalette *iface, BOOL *pfIsBla
 
     if (!pfIsBlackWhite) return E_INVALIDARG;
 
+    EnterCriticalSection(&This->lock);
     if (This->type == WICBitmapPaletteTypeFixedBW)
         *pfIsBlackWhite = TRUE;
     else
         *pfIsBlackWhite = FALSE;
+    LeaveCriticalSection(&This->lock);
 
     return S_OK;
 }
@@ -208,6 +223,7 @@ static HRESULT WINAPI PaletteImpl_IsGrayscale(IWICPalette *iface, BOOL *pfIsGray
 
     if (!pfIsGrayscale) return E_INVALIDARG;
 
+    EnterCriticalSection(&This->lock);
     switch(This->type)
     {
         case WICBitmapPaletteTypeFixedBW:
@@ -219,6 +235,7 @@ static HRESULT WINAPI PaletteImpl_IsGrayscale(IWICPalette *iface, BOOL *pfIsGray
         default:
             *pfIsGrayscale = FALSE;
     }
+    LeaveCriticalSection(&This->lock);
 
     return S_OK;
 }
@@ -234,12 +251,14 @@ static HRESULT WINAPI PaletteImpl_HasAlpha(IWICPalette *iface, BOOL *pfHasAlpha)
 
     *pfHasAlpha = FALSE;
 
+    EnterCriticalSection(&This->lock);
     for (i=0; i<This->count; i++)
         if ((This->colors[i]&0xff000000) != 0xff000000)
         {
             *pfHasAlpha = TRUE;
             break;
         }
+    LeaveCriticalSection(&This->lock);
 
     return S_OK;
 }
@@ -272,6 +291,8 @@ HRESULT PaletteImpl_Create(IWICPalette **palette)
     This->count = 0;
     This->colors = NULL;
     This->type = WICBitmapPaletteTypeCustom;
+    InitializeCriticalSection(&This->lock);
+    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PaletteImpl.lock");
 
     *palette = (IWICPalette*)This;
 
index 5af680e..3dcbd9a 100644 (file)
@@ -162,6 +162,7 @@ typedef struct {
     UINT stride;
     const WICPixelFormatGUID *format;
     BYTE *image_bits;
+    CRITICAL_SECTION lock; /* must be held when png structures are accessed or initialized is set */
 } PngDecoder;
 
 static inline PngDecoder *impl_from_frame(IWICBitmapFrameDecode *iface)
@@ -214,6 +215,8 @@ static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface)
     {
         if (This->png_ptr)
             ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info);
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
         HeapFree(GetProcessHeap(), 0, This->image_bits);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -246,7 +249,7 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
 {
     PngDecoder *This = (PngDecoder*)iface;
     LARGE_INTEGER seek;
-    HRESULT hr;
+    HRESULT hr=S_OK;
     png_bytep *row_pointers=NULL;
     UINT image_size;
     UINT i;
@@ -259,16 +262,23 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
 
     TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
 
+    EnterCriticalSection(&This->lock);
+
     /* initialize libpng */
     This->png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-    if (!This->png_ptr) return E_FAIL;
+    if (!This->png_ptr)
+    {
+        hr = E_FAIL;
+        goto end;
+    }
 
     This->info_ptr = ppng_create_info_struct(This->png_ptr);
     if (!This->info_ptr)
     {
         ppng_destroy_read_struct(&This->png_ptr, NULL, NULL);
         This->png_ptr = NULL;
-        return E_FAIL;
+        hr = E_FAIL;
+        goto end;
     }
 
     This->end_info = ppng_create_info_struct(This->png_ptr);
@@ -276,7 +286,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
     {
         ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, NULL);
         This->png_ptr = NULL;
-        return E_FAIL;
+        hr = E_FAIL;
+        goto end;
     }
 
     /* set up setjmp/longjmp error handling */
@@ -285,14 +296,15 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
         ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info);
         HeapFree(GetProcessHeap(), 0, row_pointers);
         This->png_ptr = NULL;
-        return E_FAIL;
+        hr = E_FAIL;
+        goto end;
     }
     ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn);
 
     /* seek to the start of the stream */
     seek.QuadPart = 0;
     hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
-    if (FAILED(hr)) return hr;
+    if (FAILED(hr)) goto end;
 
     /* set up custom i/o handling */
     ppng_set_read_fn(This->png_ptr, pIStream, user_read_data);
@@ -340,7 +352,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
         case 16: This->format = &GUID_WICPixelFormat16bppGray; break;
         default:
             ERR("invalid grayscale bit depth: %i\n", bit_depth);
-            return E_FAIL;
+            hr = E_FAIL;
+            goto end;
         }
         break;
     case PNG_COLOR_TYPE_GRAY_ALPHA:
@@ -357,7 +370,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
         case 16: This->format = &GUID_WICPixelFormat64bppRGBA; break;
         default:
             ERR("invalid RGBA bit depth: %i\n", bit_depth);
-            return E_FAIL;
+            hr = E_FAIL;
+            goto end;
         }
         break;
     case PNG_COLOR_TYPE_PALETTE:
@@ -370,7 +384,8 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
         case 8: This->format = &GUID_WICPixelFormat8bppIndexed; break;
         default:
             ERR("invalid indexed color bit depth: %i\n", bit_depth);
-            return E_FAIL;
+            hr = E_FAIL;
+            goto end;
         }
         break;
     case PNG_COLOR_TYPE_RGB:
@@ -384,12 +399,14 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
         case 16: This->format = &GUID_WICPixelFormat48bppRGB; break;
         default:
             ERR("invalid RGB color bit depth: %i\n", bit_depth);
-            return E_FAIL;
+            hr = E_FAIL;
+            goto end;
         }
         break;
     default:
         ERR("invalid color type %i\n", color_type);
-        return E_FAIL;
+        hr = E_FAIL;
+        goto end;
     }
 
     /* read the image data */
@@ -399,10 +416,18 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
     image_size = This->stride * This->height;
 
     This->image_bits = HeapAlloc(GetProcessHeap(), 0, image_size);
-    if (!This->image_bits) return E_OUTOFMEMORY;
+    if (!This->image_bits)
+    {
+        hr = E_OUTOFMEMORY;
+        goto end;
+    }
 
     row_pointers = HeapAlloc(GetProcessHeap(), 0, sizeof(png_bytep)*This->height);
-    if (!row_pointers) return E_OUTOFMEMORY;
+    if (!row_pointers)
+    {
+        hr = E_OUTOFMEMORY;
+        goto end;
+    }
 
     for (i=0; i<This->height; i++)
         row_pointers[i] = This->image_bits + i * This->stride;
@@ -416,7 +441,11 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
 
     This->initialized = TRUE;
 
-    return S_OK;
+end:
+
+    LeaveCriticalSection(&This->lock);
+
+    return hr;
 }
 
 static HRESULT WINAPI PngDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
@@ -570,6 +599,8 @@ static HRESULT WINAPI PngDecoder_Frame_GetResolution(IWICBitmapFrameDecode *ifac
     png_uint_32 ret, xres, yres;
     int unit_type;
 
+    EnterCriticalSection(&This->lock);
+
     ret = ppng_get_pHYs(This->png_ptr, This->info_ptr, &xres, &yres, &unit_type);
 
     if (ret && unit_type == PNG_RESOLUTION_METER)
@@ -583,6 +614,8 @@ static HRESULT WINAPI PngDecoder_Frame_GetResolution(IWICBitmapFrameDecode *ifac
         *pDpiX = *pDpiY = 96.0;
     }
 
+    LeaveCriticalSection(&This->lock);
+
     TRACE("(%p)->(%0.2f,%0.2f)\n", iface, *pDpiX, *pDpiY);
 
     return S_OK;
@@ -600,16 +633,24 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
     int num_trans;
     png_color_16p trans_values;
     int i;
+    HRESULT hr=S_OK;
 
     TRACE("(%p,%p)\n", iface, pIPalette);
 
+    EnterCriticalSection(&This->lock);
+
     ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette);
-    if (!ret) return WINCODEC_ERR_PALETTEUNAVAILABLE;
+    if (!ret)
+    {
+        hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
+        goto end;
+    }
 
     if (num_palette > 256)
     {
         ERR("palette has %i colors?!\n", num_palette);
-        return E_FAIL;
+        hr = E_FAIL;
+        goto end;
     }
 
     for (i=0; i<num_palette; i++)
@@ -629,7 +670,14 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
         }
     }
 
-    return IWICPalette_InitializeCustom(pIPalette, palette, num_palette);
+end:
+
+    LeaveCriticalSection(&This->lock);
+
+    if (SUCCEEDED(hr))
+        hr = IWICPalette_InitializeCustom(pIPalette, palette, num_palette);
+
+    return hr;
 }
 
 static HRESULT WINAPI PngDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
@@ -706,6 +754,8 @@ HRESULT PngDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
     This->end_info = NULL;
     This->initialized = FALSE;
     This->image_bits = NULL;
+    InitializeCriticalSection(&This->lock);
+    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngDecoder.lock");
 
     ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
     IUnknown_Release((IUnknown*)This);
@@ -752,6 +802,7 @@ typedef struct PngEncoder {
     UINT lines_written;
     BOOL frame_committed;
     BOOL committed;
+    CRITICAL_SECTION lock;
 } PngEncoder;
 
 static inline PngEncoder *encoder_from_frame(IWICBitmapFrameEncode *iface)
@@ -800,10 +851,18 @@ static HRESULT WINAPI PngFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
     PngEncoder *This = encoder_from_frame(iface);
     TRACE("(%p,%p)\n", iface, pIEncoderOptions);
 
-    if (This->frame_initialized) return WINCODEC_ERR_WRONGSTATE;
+    EnterCriticalSection(&This->lock);
+
+    if (This->frame_initialized)
+    {
+        LeaveCriticalSection(&This->lock);
+        return WINCODEC_ERR_WRONGSTATE;
+    }
 
     This->frame_initialized = TRUE;
 
+    LeaveCriticalSection(&This->lock);
+
     return S_OK;
 }
 
@@ -813,11 +872,19 @@ static HRESULT WINAPI PngFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
     PngEncoder *This = encoder_from_frame(iface);
     TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight);
 
-    if (!This->frame_initialized || This->info_written) return WINCODEC_ERR_WRONGSTATE;
+    EnterCriticalSection(&This->lock);
+
+    if (!This->frame_initialized || This->info_written)
+    {
+        LeaveCriticalSection(&This->lock);
+        return WINCODEC_ERR_WRONGSTATE;
+    }
 
     This->width = uiWidth;
     This->height = uiHeight;
 
+    LeaveCriticalSection(&This->lock);
+
     return S_OK;
 }
 
@@ -827,11 +894,19 @@ static HRESULT WINAPI PngFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
     PngEncoder *This = encoder_from_frame(iface);
     TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);
 
-    if (!This->frame_initialized || This->info_written) return WINCODEC_ERR_WRONGSTATE;
+    EnterCriticalSection(&This->lock);
+
+    if (!This->frame_initialized || This->info_written)
+    {
+        LeaveCriticalSection(&This->lock);
+        return WINCODEC_ERR_WRONGSTATE;
+    }
 
     This->xres = dpiX;
     This->yres = dpiY;
 
+    LeaveCriticalSection(&This->lock);
+
     return S_OK;
 }
 
@@ -842,7 +917,13 @@ static HRESULT WINAPI PngFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface
     int i;
     TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));
 
-    if (!This->frame_initialized || This->info_written) return WINCODEC_ERR_WRONGSTATE;
+    EnterCriticalSection(&This->lock);
+
+    if (!This->frame_initialized || This->info_written)
+    {
+        LeaveCriticalSection(&This->lock);
+        return WINCODEC_ERR_WRONGSTATE;
+    }
 
     for (i=0; formats[i].guid; i++)
     {
@@ -855,6 +936,8 @@ static HRESULT WINAPI PngFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface
     This->format = &formats[i];
     memcpy(pPixelFormat, This->format->guid, sizeof(GUID));
 
+    LeaveCriticalSection(&This->lock);
+
     return S_OK;
 }
 
@@ -888,15 +971,24 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
     jmp_buf jmpbuf;
     TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
 
+    EnterCriticalSection(&This->lock);
+
     if (!This->frame_initialized || !This->width || !This->height || !This->format)
+    {
+        LeaveCriticalSection(&This->lock);
         return WINCODEC_ERR_WRONGSTATE;
+    }
 
     if (lineCount == 0 || lineCount + This->lines_written > This->height)
+    {
+        LeaveCriticalSection(&This->lock);
         return E_INVALIDARG;
+    }
 
     /* set up setjmp/longjmp error handling */
     if (setjmp(jmpbuf))
     {
+        LeaveCriticalSection(&This->lock);
         HeapFree(GetProcessHeap(), 0, row_pointers);
         return E_FAIL;
     }
@@ -927,7 +1019,10 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
 
     row_pointers = HeapAlloc(GetProcessHeap(), 0, lineCount * sizeof(png_byte*));
     if (!row_pointers)
+    {
+        LeaveCriticalSection(&This->lock);
         return E_OUTOFMEMORY;
+    }
 
     for (i=0; i<lineCount; i++)
         row_pointers[i] = pbPixels + cbStride * i;
@@ -935,6 +1030,8 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
     ppng_write_rows(This->png_ptr, row_pointers, lineCount);
     This->lines_written += lineCount;
 
+    LeaveCriticalSection(&This->lock);
+
     HeapFree(GetProcessHeap(), 0, row_pointers);
 
     return S_OK;
@@ -1019,12 +1116,18 @@ static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface)
     jmp_buf jmpbuf;
     TRACE("(%p)\n", iface);
 
+    EnterCriticalSection(&This->lock);
+
     if (!This->info_written || This->lines_written != This->height || This->frame_committed)
+    {
+        LeaveCriticalSection(&This->lock);
         return WINCODEC_ERR_WRONGSTATE;
+    }
 
     /* set up setjmp/longjmp error handling */
     if (setjmp(jmpbuf))
     {
+        LeaveCriticalSection(&This->lock);
         return E_FAIL;
     }
     ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn);
@@ -1033,6 +1136,8 @@ static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface)
 
     This->frame_committed = TRUE;
 
+    LeaveCriticalSection(&This->lock);
+
     return S_OK;
 }
 
@@ -1102,6 +1207,8 @@ static ULONG WINAPI PngEncoder_Release(IWICBitmapEncoder *iface)
 
     if (ref == 0)
     {
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
         if (This->png_ptr)
             ppng_destroy_write_struct(&This->png_ptr, &This->info_ptr);
         if (This->stream)
@@ -1137,19 +1244,28 @@ static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface,
 
     TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption);
 
+    EnterCriticalSection(&This->lock);
+
     if (This->png_ptr)
+    {
+        LeaveCriticalSection(&This->lock);
         return WINCODEC_ERR_WRONGSTATE;
+    }
 
     /* initialize libpng */
     This->png_ptr = ppng_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
     if (!This->png_ptr)
+    {
+        LeaveCriticalSection(&This->lock);
         return E_FAIL;
+    }
 
     This->info_ptr = ppng_create_info_struct(This->png_ptr);
     if (!This->info_ptr)
     {
         ppng_destroy_write_struct(&This->png_ptr, NULL);
         This->png_ptr = NULL;
+        LeaveCriticalSection(&This->lock);
         return E_FAIL;
     }
 
@@ -1163,6 +1279,7 @@ static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface,
         This->png_ptr = NULL;
         IStream_Release(This->stream);
         This->stream = NULL;
+        LeaveCriticalSection(&This->lock);
         return E_FAIL;
     }
     ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn);
@@ -1170,6 +1287,8 @@ static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface,
     /* set up custom i/o handling */
     ppng_set_write_fn(This->png_ptr, This, user_write_data, user_flush);
 
+    LeaveCriticalSection(&This->lock);
+
     return S_OK;
 }
 
@@ -1219,17 +1338,31 @@ static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
     HRESULT hr;
     TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
 
+    EnterCriticalSection(&This->lock);
+
     if (This->frame_count != 0)
+    {
+        LeaveCriticalSection(&This->lock);
         return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+    }
 
     if (!This->stream)
+    {
+        LeaveCriticalSection(&This->lock);
         return WINCODEC_ERR_NOTINITIALIZED;
+    }
 
     hr = CreatePropertyBag2(ppIEncoderOptions);
-    if (FAILED(hr)) return hr;
+    if (FAILED(hr))
+    {
+        LeaveCriticalSection(&This->lock);
+        return hr;
+    }
 
     This->frame_count = 1;
 
+    LeaveCriticalSection(&This->lock);
+
     IWICBitmapEncoder_AddRef(iface);
     *ppIFrameEncode = (IWICBitmapFrameEncode*)&This->lpFrameVtbl;
 
@@ -1241,11 +1374,18 @@ static HRESULT WINAPI PngEncoder_Commit(IWICBitmapEncoder *iface)
     PngEncoder *This = (PngEncoder*)iface;
     TRACE("(%p)\n", iface);
 
+    EnterCriticalSection(&This->lock);
+
     if (!This->frame_committed || This->committed)
+    {
+        LeaveCriticalSection(&This->lock);
         return WINCODEC_ERR_WRONGSTATE;
+    }
 
     This->committed = TRUE;
 
+    EnterCriticalSection(&This->lock);
+
     return S_OK;
 }
 
@@ -1309,6 +1449,8 @@ HRESULT PngEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
     This->lines_written = 0;
     This->frame_committed = FALSE;
     This->committed = FALSE;
+    InitializeCriticalSection(&This->lock);
+    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngEncoder.lock");
 
     ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
     IUnknown_Release((IUnknown*)This);
index c87aa4b..c5828a6 100644 (file)
@@ -727,25 +727,25 @@ static struct regsvr_coclass const coclass_list[] = {
        "WIC Imaging Factory",
        NULL,
        "windowscodecs.dll",
-       "Apartment"
+       "Both"
     },
     {   &CLSID_WICBmpDecoder,
        "WIC BMP Decoder",
        NULL,
        "windowscodecs.dll",
-       "Apartment"
+       "Both"
     },
     {   &CLSID_WICPngDecoder,
        "WIC PNG Decoder",
        NULL,
        "windowscodecs.dll",
-       "Apartment"
+       "Both"
     },
     {   &CLSID_WICPngEncoder,
        "WIC PNG Encoder",
        NULL,
        "windowscodecs.dll",
-       "Apartment"
+       "Both"
     },
     {   &CLSID_WICBmpEncoder,
        "WIC BMP Encoder",
@@ -757,25 +757,31 @@ static struct regsvr_coclass const coclass_list[] = {
        "WIC GIF Decoder",
        NULL,
        "windowscodecs.dll",
-       "Apartment"
+       "Both"
     },
     {   &CLSID_WICIcoDecoder,
        "WIC ICO Decoder",
        NULL,
        "windowscodecs.dll",
-       "Apartment"
+       "Both"
     },
     {   &CLSID_WICJpegDecoder,
        "WIC JPEG Decoder",
        NULL,
        "windowscodecs.dll",
-       "Apartment"
+       "Both"
+    },
+    {   &CLSID_WICTiffDecoder,
+       "WIC TIFF Decoder",
+       NULL,
+       "windowscodecs.dll",
+       "Both"
     },
     {   &CLSID_WICDefaultFormatConverter,
        "WIC Default Format Converter",
        NULL,
        "windowscodecs.dll",
-       "Apartment"
+       "Both"
     },
     { NULL }                   /* list terminator */
 };
@@ -868,6 +874,27 @@ static struct decoder_pattern const png_patterns[] = {
     {0}
 };
 
+static const BYTE tiff_magic_le[] = {0x49,0x49,42,0};
+static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42};
+
+static GUID const * const tiff_formats[] = {
+    &GUID_WICPixelFormatBlackWhite,
+    &GUID_WICPixelFormat4bppGray,
+    &GUID_WICPixelFormat8bppGray,
+    &GUID_WICPixelFormat4bppIndexed,
+    &GUID_WICPixelFormat8bppIndexed,
+    &GUID_WICPixelFormat32bppBGR,
+    &GUID_WICPixelFormat32bppBGRA,
+    &GUID_WICPixelFormat32bppPBGRA,
+    NULL
+};
+
+static struct decoder_pattern const tiff_patterns[] = {
+    {4,0,tiff_magic_le,mask_all,0},
+    {4,0,tiff_magic_be,mask_all,0},
+    {0}
+};
+
 static struct regsvr_decoder const decoder_list[] = {
     {   &CLSID_WICBmpDecoder,
        "The Wine Project",
@@ -919,6 +946,16 @@ static struct regsvr_decoder const decoder_list[] = {
        png_formats,
        png_patterns
     },
+    {   &CLSID_WICTiffDecoder,
+       "The Wine Project",
+       "TIFF Decoder",
+       "1.0.0.0",
+       &GUID_VendorMicrosoft,
+       "image/tiff",
+       ".tif;.tiff",
+       tiff_formats,
+       tiff_patterns
+    },
     { NULL }                   /* list terminator */
 };
 
index c59a9d2..bd5592b 100644 (file)
@@ -41,6 +41,8 @@ typedef struct StreamOnMemory {
     BYTE *pbMemory;
     DWORD dwMemsize;
     DWORD dwCurPos;
+
+    CRITICAL_SECTION lock; /* must be held when pbMemory or dwCurPos is accessed */
 } StreamOnMemory;
 
 static HRESULT WINAPI StreamOnMemory_QueryInterface(IStream *iface,
@@ -82,6 +84,8 @@ static ULONG WINAPI StreamOnMemory_Release(IStream *iface)
     TRACE("(%p) refcount=%u\n", iface, ref);
 
     if (ref == 0) {
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
@@ -96,9 +100,12 @@ static HRESULT WINAPI StreamOnMemory_Read(IStream *iface,
 
     if (!pv) return E_INVALIDARG;
 
+    EnterCriticalSection(&This->lock);
     uBytesRead = min(cb, This->dwMemsize - This->dwCurPos);
     memcpy(pv, This->pbMemory + This->dwCurPos, uBytesRead);
     This->dwCurPos += uBytesRead;
+    LeaveCriticalSection(&This->lock);
+
     if (pcbRead) *pcbRead = uBytesRead;
 
     return S_OK;
@@ -108,18 +115,24 @@ static HRESULT WINAPI StreamOnMemory_Write(IStream *iface,
     void const *pv, ULONG cb, ULONG *pcbWritten)
 {
     StreamOnMemory *This = (StreamOnMemory*)iface;
+    HRESULT hr;
     TRACE("(%p)\n", This);
 
     if (!pv) return E_INVALIDARG;
 
-    if (cb > This->dwMemsize - This->dwCurPos) return STG_E_MEDIUMFULL;
-    if (cb) {
+    EnterCriticalSection(&This->lock);
+    if (cb > This->dwMemsize - This->dwCurPos) {
+        hr = STG_E_MEDIUMFULL;
+    }
+    else {
         memcpy(This->pbMemory + This->dwCurPos, pv, cb);
         This->dwCurPos += cb;
+        hr = S_OK;
+        if (pcbWritten) *pcbWritten = cb;
     }
-    if (pcbWritten) *pcbWritten = cb;
+    LeaveCriticalSection(&This->lock);
 
-    return S_OK;
+    return hr;
 }
 
 static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface,
@@ -127,20 +140,29 @@ static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface,
 {
     StreamOnMemory *This = (StreamOnMemory*)iface;
     LARGE_INTEGER NewPosition;
+    HRESULT hr=S_OK;
     TRACE("(%p)\n", This);
 
+    EnterCriticalSection(&This->lock);
     if (dwOrigin == STREAM_SEEK_SET) NewPosition.QuadPart = dlibMove.QuadPart;
     else if (dwOrigin == STREAM_SEEK_CUR) NewPosition.QuadPart = This->dwCurPos + dlibMove.QuadPart;
     else if (dwOrigin == STREAM_SEEK_END) NewPosition.QuadPart = This->dwMemsize + dlibMove.QuadPart;
-    else return E_INVALIDARG;
+    else hr = E_INVALIDARG;
 
-    if (NewPosition.u.HighPart) return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
-    if (NewPosition.QuadPart > This->dwMemsize) return E_INVALIDARG;
-    if (NewPosition.QuadPart < 0) return E_INVALIDARG;
-    This->dwCurPos = NewPosition.u.LowPart;
+    if (SUCCEEDED(hr)) {
+        if (NewPosition.u.HighPart) hr = HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
+        else if (NewPosition.QuadPart > This->dwMemsize) hr = E_INVALIDARG;
+        else if (NewPosition.QuadPart < 0) hr = E_INVALIDARG;
+    }
 
-    if(plibNewPosition) plibNewPosition->QuadPart = This->dwCurPos;
-    return S_OK;
+    if (SUCCEEDED(hr)) {
+        This->dwCurPos = NewPosition.u.LowPart;
+
+        if(plibNewPosition) plibNewPosition->QuadPart = This->dwCurPos;
+    }
+    LeaveCriticalSection(&This->lock);
+
+    return hr;
 }
 
 /* SetSize isn't implemented in the native windowscodecs DLL either */
@@ -450,8 +472,16 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface,
     pObject->pbMemory = pbBuffer;
     pObject->dwMemsize = cbBufferSize;
     pObject->dwCurPos = 0;
+    InitializeCriticalSection(&pObject->lock);
+    pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnMemory.lock");
+
+    if (InterlockedCompareExchangePointer((void**)&This->pStream, pObject, NULL))
+    {
+        /* Some other thread set the stream first. */
+        IStream_Release((IStream*)pObject);
+        return WINCODEC_ERR_WRONGSTATE;
+    }
 
-    This->pStream = (IStream*)pObject;
     return S_OK;
 }
 
diff --git a/dll/win32/windowscodecs/tiffformat.c b/dll/win32/windowscodecs/tiffformat.c
new file mode 100644 (file)
index 0000000..fe87ddd
--- /dev/null
@@ -0,0 +1,866 @@
+/*
+ * Copyright 2010 Vincent Povirk for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_TIFFIO_H
+#include <tiffio.h>
+#endif
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "objbase.h"
+#include "wincodec.h"
+
+#include "wincodecs_private.h"
+
+#include "wine/debug.h"
+#include "wine/library.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
+
+#ifdef SONAME_LIBTIFF
+
+static CRITICAL_SECTION init_tiff_cs;
+static CRITICAL_SECTION_DEBUG init_tiff_cs_debug =
+{
+    0, 0, &init_tiff_cs,
+    { &init_tiff_cs_debug.ProcessLocksList,
+      &init_tiff_cs_debug.ProcessLocksList },
+    0, 0, { (DWORD_PTR)(__FILE__ ": init_tiff_cs") }
+};
+static CRITICAL_SECTION init_tiff_cs = { &init_tiff_cs_debug, -1, 0, 0, 0, 0 };
+
+static void *libtiff_handle;
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f
+MAKE_FUNCPTR(TIFFClientOpen);
+MAKE_FUNCPTR(TIFFClose);
+MAKE_FUNCPTR(TIFFCurrentDirectory);
+MAKE_FUNCPTR(TIFFGetField);
+MAKE_FUNCPTR(TIFFReadDirectory);
+MAKE_FUNCPTR(TIFFReadEncodedStrip);
+MAKE_FUNCPTR(TIFFSetDirectory);
+#undef MAKE_FUNCPTR
+
+static void *load_libtiff(void)
+{
+    void *result;
+
+    EnterCriticalSection(&init_tiff_cs);
+
+    if (!libtiff_handle &&
+        (libtiff_handle = wine_dlopen(SONAME_LIBTIFF, RTLD_NOW, NULL, 0)) != NULL)
+    {
+
+#define LOAD_FUNCPTR(f) \
+    if((p##f = wine_dlsym(libtiff_handle, #f, NULL, 0)) == NULL) { \
+        ERR("failed to load symbol %s\n", #f); \
+        libtiff_handle = NULL; \
+        LeaveCriticalSection(&init_tiff_cs); \
+        return NULL; \
+    }
+        LOAD_FUNCPTR(TIFFClientOpen);
+        LOAD_FUNCPTR(TIFFClose);
+        LOAD_FUNCPTR(TIFFCurrentDirectory);
+        LOAD_FUNCPTR(TIFFGetField);
+        LOAD_FUNCPTR(TIFFReadDirectory);
+        LOAD_FUNCPTR(TIFFReadEncodedStrip);
+        LOAD_FUNCPTR(TIFFSetDirectory);
+#undef LOAD_FUNCPTR
+
+    }
+
+    result = libtiff_handle;
+
+    LeaveCriticalSection(&init_tiff_cs);
+    return result;
+}
+
+static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t size)
+{
+    IStream *stream = (IStream*)client_data;
+    ULONG bytes_read;
+    HRESULT hr;
+
+    hr = IStream_Read(stream, data, size, &bytes_read);
+    if (FAILED(hr)) bytes_read = 0;
+    return bytes_read;
+}
+
+static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t size)
+{
+    IStream *stream = (IStream*)client_data;
+    ULONG bytes_written;
+    HRESULT hr;
+
+    hr = IStream_Write(stream, data, size, &bytes_written);
+    if (FAILED(hr)) bytes_written = 0;
+    return bytes_written;
+}
+
+static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence)
+{
+    IStream *stream = (IStream*)client_data;
+    LARGE_INTEGER move;
+    DWORD origin;
+    ULARGE_INTEGER new_position;
+    HRESULT hr;
+
+    move.QuadPart = offset;
+    switch (whence)
+    {
+        case SEEK_SET:
+            origin = STREAM_SEEK_SET;
+            break;
+        case SEEK_CUR:
+            origin = STREAM_SEEK_CUR;
+            break;
+        case SEEK_END:
+            origin = STREAM_SEEK_END;
+            break;
+        default:
+            ERR("unknown whence value %i\n", whence);
+            return -1;
+    }
+
+    hr = IStream_Seek(stream, move, origin, &new_position);
+    if (SUCCEEDED(hr)) return new_position.QuadPart;
+    else return -1;
+}
+
+static int tiff_stream_close(thandle_t client_data)
+{
+    /* Caller is responsible for releasing the stream object. */
+    return 0;
+}
+
+static toff_t tiff_stream_size(thandle_t client_data)
+{
+    IStream *stream = (IStream*)client_data;
+    STATSTG statstg;
+    HRESULT hr;
+
+    hr = IStream_Stat(stream, &statstg, STATFLAG_NONAME);
+
+    if (SUCCEEDED(hr)) return statstg.cbSize.QuadPart;
+    else return -1;
+}
+
+static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size)
+{
+    /* Cannot mmap streams */
+    return 0;
+}
+
+static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size)
+{
+    /* No need to ever do this, since we can't map things. */
+}
+
+static TIFF* tiff_open_stream(IStream *stream, const char *mode)
+{
+    return pTIFFClientOpen("<IStream object>", mode, stream, tiff_stream_read,
+        tiff_stream_write, tiff_stream_seek, tiff_stream_close,
+        tiff_stream_size, tiff_stream_map, tiff_stream_unmap);
+}
+
+typedef struct {
+    const IWICBitmapDecoderVtbl *lpVtbl;
+    LONG ref;
+    IStream *stream;
+    CRITICAL_SECTION lock; /* Must be held when tiff is used or initiailzed is set */
+    TIFF *tiff;
+    BOOL initialized;
+} TiffDecoder;
+
+typedef struct {
+    const WICPixelFormatGUID *format;
+    int bpp;
+    int indexed;
+    int reverse_bgr;
+    UINT width, height;
+    UINT tile_width, tile_height;
+    UINT tile_stride;
+    UINT tile_size;
+} tiff_decode_info;
+
+typedef struct {
+    const IWICBitmapFrameDecodeVtbl *lpVtbl;
+    LONG ref;
+    TiffDecoder *parent;
+    UINT index;
+    tiff_decode_info decode_info;
+    INT cached_tile_x, cached_tile_y;
+    BYTE *cached_tile;
+} TiffFrameDecode;
+
+static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl;
+
+static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
+{
+    uint16 photometric, bps, samples, planar;
+    int ret;
+
+    decode_info->indexed = 0;
+    decode_info->reverse_bgr = 0;
+
+    ret = pTIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
+    if (!ret)
+    {
+        WARN("missing PhotometricInterpretation tag\n");
+        return E_FAIL;
+    }
+
+    ret = pTIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bps);
+    if (!ret) bps = 1;
+
+    switch(photometric)
+    {
+    case 1: /* BlackIsZero */
+        decode_info->bpp = bps;
+        switch (bps)
+        {
+        case 1:
+            decode_info->format = &GUID_WICPixelFormatBlackWhite;
+            break;
+        case 4:
+            decode_info->format = &GUID_WICPixelFormat4bppGray;
+            break;
+        case 8:
+            decode_info->format = &GUID_WICPixelFormat8bppGray;
+            break;
+        default:
+            FIXME("unhandled greyscale bit count %u\n", bps);
+            return E_FAIL;
+        }
+        break;
+    case 2: /* RGB */
+        if (bps != 8)
+        {
+            FIXME("unhandled RGB bit count %u\n", bps);
+            return E_FAIL;
+        }
+        ret = pTIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samples);
+        if (samples != 3)
+        {
+            FIXME("unhandled RGB sample count %u\n", samples);
+            return E_FAIL;
+        }
+        ret = pTIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planar);
+        if (!ret) planar = 1;
+        if (planar != 1)
+        {
+            FIXME("unhandled planar configuration %u\n", planar);
+            return E_FAIL;
+        }
+        decode_info->bpp = bps * samples;
+        decode_info->reverse_bgr = 1;
+        decode_info->format = &GUID_WICPixelFormat24bppBGR;
+        break;
+    case 3: /* RGB Palette */
+        decode_info->indexed = 1;
+        decode_info->bpp = bps;
+        switch (bps)
+        {
+        case 4:
+            decode_info->format = &GUID_WICPixelFormat4bppIndexed;
+            break;
+        case 8:
+            decode_info->format = &GUID_WICPixelFormat8bppIndexed;
+            break;
+        default:
+            FIXME("unhandled indexed bit count %u\n", bps);
+            return E_FAIL;
+        }
+        break;
+    case 0: /* WhiteIsZero */
+    case 4: /* Transparency mask */
+    case 5: /* CMYK */
+    case 6: /* YCbCr */
+    case 8: /* CIELab */
+    default:
+        FIXME("unhandled PhotometricInterpretation %u\n", photometric);
+        return E_FAIL;
+    }
+
+    ret = pTIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &decode_info->width);
+    if (!ret)
+    {
+        WARN("missing image width\n");
+        return E_FAIL;
+    }
+
+    ret = pTIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &decode_info->height);
+    if (!ret)
+    {
+        WARN("missing image length\n");
+        return E_FAIL;
+    }
+
+    ret = pTIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &decode_info->tile_height);
+    if (ret)
+    {
+        decode_info->tile_width = decode_info->width;
+        decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8);
+        decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride;
+    }
+    else
+    {
+        /* Probably a tiled image */
+        FIXME("missing RowsPerStrip value\n");
+        return E_FAIL;
+    }
+
+    return S_OK;
+}
+
+static HRESULT WINAPI TiffDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
+    void **ppv)
+{
+    TiffDecoder *This = (TiffDecoder*)iface;
+    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
+
+    if (!ppv) return E_INVALIDARG;
+
+    if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid))
+    {
+        *ppv = This;
+    }
+    else
+    {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI TiffDecoder_AddRef(IWICBitmapDecoder *iface)
+{
+    TiffDecoder *This = (TiffDecoder*)iface;
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) refcount=%u\n", iface, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI TiffDecoder_Release(IWICBitmapDecoder *iface)
+{
+    TiffDecoder *This = (TiffDecoder*)iface;
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) refcount=%u\n", iface, ref);
+
+    if (ref == 0)
+    {
+        if (This->tiff) pTIFFClose(This->tiff);
+        if (This->stream) IStream_Release(This->stream);
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI TiffDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *pIStream,
+    DWORD *pdwCapability)
+{
+    FIXME("(%p,%p,%p): stub\n", iface, pIStream, pdwCapability);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
+    WICDecodeOptions cacheOptions)
+{
+    TiffDecoder *This = (TiffDecoder*)iface;
+    TIFF *tiff;
+    HRESULT hr=S_OK;
+
+    TRACE("(%p,%p,%x): stub\n", iface, pIStream, cacheOptions);
+
+    EnterCriticalSection(&This->lock);
+
+    if (This->initialized)
+    {
+        hr = WINCODEC_ERR_WRONGSTATE;
+        goto exit;
+    }
+
+    tiff = tiff_open_stream(pIStream, "r");
+
+    if (!tiff)
+    {
+        hr = E_FAIL;
+        goto exit;
+    }
+
+    This->tiff = tiff;
+    This->stream = pIStream;
+    IStream_AddRef(pIStream);
+    This->initialized = TRUE;
+
+exit:
+    LeaveCriticalSection(&This->lock);
+    return hr;
+}
+
+static HRESULT WINAPI TiffDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
+    GUID *pguidContainerFormat)
+{
+    memcpy(pguidContainerFormat, &GUID_ContainerFormatTiff, sizeof(GUID));
+    return S_OK;
+}
+
+static HRESULT WINAPI TiffDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
+    IWICBitmapDecoderInfo **ppIDecoderInfo)
+{
+    FIXME("(%p,%p): stub\n", iface, ppIDecoderInfo);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffDecoder_CopyPalette(IWICBitmapDecoder *iface,
+    IWICPalette *pIPalette)
+{
+    FIXME("(%p,%p): stub\n", iface, pIPalette);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
+    IWICMetadataQueryReader **ppIMetadataQueryReader)
+{
+    FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffDecoder_GetPreview(IWICBitmapDecoder *iface,
+    IWICBitmapSource **ppIBitmapSource)
+{
+    FIXME("(%p,%p): stub\n", iface, ppIBitmapSource);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffDecoder_GetColorContexts(IWICBitmapDecoder *iface,
+    UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
+{
+    FIXME("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffDecoder_GetThumbnail(IWICBitmapDecoder *iface,
+    IWICBitmapSource **ppIThumbnail)
+{
+    TRACE("(%p,%p)\n", iface, ppIThumbnail);
+    return WINCODEC_ERR_CODECNOTHUMBNAIL;
+}
+
+static HRESULT WINAPI TiffDecoder_GetFrameCount(IWICBitmapDecoder *iface,
+    UINT *pCount)
+{
+    TiffDecoder *This = (TiffDecoder*)iface;
+
+    if (!This->tiff)
+    {
+        WARN("(%p) <-- WINCODEC_ERR_WRONGSTATE\n", iface);
+        return WINCODEC_ERR_WRONGSTATE;
+    }
+
+    EnterCriticalSection(&This->lock);
+    while (pTIFFReadDirectory(This->tiff)) { }
+    *pCount = pTIFFCurrentDirectory(This->tiff)+1;
+    LeaveCriticalSection(&This->lock);
+
+    TRACE("(%p) <-- %i\n", iface, *pCount);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI TiffDecoder_GetFrame(IWICBitmapDecoder *iface,
+    UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
+{
+    TiffDecoder *This = (TiffDecoder*)iface;
+    TiffFrameDecode *result;
+    int res;
+    tiff_decode_info decode_info;
+    HRESULT hr;
+
+    TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
+
+    if (!This->tiff)
+        return WINCODEC_ERR_WRONGSTATE;
+
+    EnterCriticalSection(&This->lock);
+    res = pTIFFSetDirectory(This->tiff, index);
+    if (!res) hr = E_INVALIDARG;
+    else hr = tiff_get_decode_info(This->tiff, &decode_info);
+    LeaveCriticalSection(&This->lock);
+
+    if (SUCCEEDED(hr))
+    {
+        result = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffFrameDecode));
+
+        if (result)
+        {
+            result->lpVtbl = &TiffFrameDecode_Vtbl;
+            result->ref = 1;
+            result->parent = This;
+            result->index = index;
+            result->decode_info = decode_info;
+            result->cached_tile_x = -1;
+            result->cached_tile = HeapAlloc(GetProcessHeap(), 0, decode_info.tile_size);
+
+            if (result->cached_tile)
+                *ppIBitmapFrame = (IWICBitmapFrameDecode*)result;
+            else
+            {
+                hr = E_OUTOFMEMORY;
+                HeapFree(GetProcessHeap(), 0, result);
+            }
+        }
+        else hr = E_OUTOFMEMORY;
+    }
+
+    if (FAILED(hr)) *ppIBitmapFrame = NULL;
+
+    return hr;
+}
+
+static const IWICBitmapDecoderVtbl TiffDecoder_Vtbl = {
+    TiffDecoder_QueryInterface,
+    TiffDecoder_AddRef,
+    TiffDecoder_Release,
+    TiffDecoder_QueryCapability,
+    TiffDecoder_Initialize,
+    TiffDecoder_GetContainerFormat,
+    TiffDecoder_GetDecoderInfo,
+    TiffDecoder_CopyPalette,
+    TiffDecoder_GetMetadataQueryReader,
+    TiffDecoder_GetPreview,
+    TiffDecoder_GetColorContexts,
+    TiffDecoder_GetThumbnail,
+    TiffDecoder_GetFrameCount,
+    TiffDecoder_GetFrame
+};
+
+static HRESULT WINAPI TiffFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
+    void **ppv)
+{
+    TiffFrameDecode *This = (TiffFrameDecode*)iface;
+    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
+
+    if (!ppv) return E_INVALIDARG;
+
+    if (IsEqualIID(&IID_IUnknown, iid) ||
+        IsEqualIID(&IID_IWICBitmapSource, iid) ||
+        IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
+    {
+        *ppv = This;
+    }
+    else
+    {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI TiffFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
+{
+    TiffFrameDecode *This = (TiffFrameDecode*)iface;
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) refcount=%u\n", iface, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI TiffFrameDecode_Release(IWICBitmapFrameDecode *iface)
+{
+    TiffFrameDecode *This = (TiffFrameDecode*)iface;
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) refcount=%u\n", iface, ref);
+
+    if (ref == 0)
+    {
+        HeapFree(GetProcessHeap(), 0, This->cached_tile);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI TiffFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
+    UINT *puiWidth, UINT *puiHeight)
+{
+    TiffFrameDecode *This = (TiffFrameDecode*)iface;
+
+    *puiWidth = This->decode_info.width;
+    *puiHeight = This->decode_info.height;
+
+    TRACE("(%p) <-- %ux%u\n", iface, *puiWidth, *puiHeight);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI TiffFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface,
+    WICPixelFormatGUID *pPixelFormat)
+{
+    TiffFrameDecode *This = (TiffFrameDecode*)iface;
+
+    memcpy(pPixelFormat, This->decode_info.format, sizeof(GUID));
+
+    TRACE("(%p) <-- %s\n", This, debugstr_guid(This->decode_info.format));
+
+    return S_OK;
+}
+
+static HRESULT WINAPI TiffFrameDecode_GetResolution(IWICBitmapFrameDecode *iface,
+    double *pDpiX, double *pDpiY)
+{
+    FIXME("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
+    IWICPalette *pIPalette)
+{
+    FIXME("(%p,%p)\n", iface, pIPalette);
+    return E_NOTIMPL;
+}
+
+static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT tile_y)
+{
+    HRESULT hr=S_OK;
+    tsize_t ret;
+
+    ret = pTIFFSetDirectory(This->parent->tiff, This->index);
+
+    if (ret == -1)
+        hr = E_FAIL;
+
+    if (hr == S_OK)
+    {
+        ret = pTIFFReadEncodedStrip(This->parent->tiff, tile_y, This->cached_tile, This->decode_info.tile_size);
+
+        if (ret == -1)
+            hr = E_FAIL;
+    }
+
+    if (hr == S_OK && This->decode_info.reverse_bgr)
+    {
+        if (This->decode_info.format == &GUID_WICPixelFormat24bppBGR)
+        {
+            UINT i, total_pixels;
+            BYTE *pixel, temp;
+
+            total_pixels = This->decode_info.tile_width * This->decode_info.tile_height;
+            pixel = This->cached_tile;
+            for (i=0; i<total_pixels; i++)
+            {
+                temp = pixel[2];
+                pixel[2] = pixel[0];
+                pixel[0] = temp;
+                pixel += 3;
+            }
+        }
+    }
+
+    if (hr == S_OK)
+    {
+        This->cached_tile_x = tile_x;
+        This->cached_tile_y = tile_y;
+    }
+
+    return hr;
+}
+
+static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
+    const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
+{
+    TiffFrameDecode *This = (TiffFrameDecode*)iface;
+    UINT min_tile_x, max_tile_x, min_tile_y, max_tile_y;
+    UINT tile_x, tile_y;
+    WICRect rc;
+    HRESULT hr=S_OK;
+    BYTE *dst_tilepos;
+    UINT bytesperrow;
+
+    TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
+
+    if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width > This->decode_info.width ||
+        prc->Y+prc->Height > This->decode_info.height)
+        return E_INVALIDARG;
+
+    bytesperrow = ((This->decode_info.bpp * prc->Width)+7)/8;
+
+    if (cbStride < bytesperrow)
+        return E_INVALIDARG;
+
+    if ((cbStride * prc->Height) > cbBufferSize)
+        return E_INVALIDARG;
+
+    min_tile_x = prc->X / This->decode_info.tile_width;
+    min_tile_y = prc->Y / This->decode_info.tile_height;
+    max_tile_x = (prc->X+prc->Width-1) / This->decode_info.tile_width;
+    max_tile_y = (prc->Y+prc->Height-1) / This->decode_info.tile_height;
+
+    EnterCriticalSection(&This->parent->lock);
+
+    for (tile_x=min_tile_x; tile_x <= max_tile_x; tile_x++)
+    {
+        for (tile_y=min_tile_y; tile_y <= max_tile_y; tile_y++)
+        {
+            if (tile_x != This->cached_tile_x || tile_y != This->cached_tile_y)
+            {
+                hr = TiffFrameDecode_ReadTile(This, tile_x, tile_y);
+            }
+
+            if (SUCCEEDED(hr))
+            {
+                if (prc->X < tile_x * This->decode_info.tile_width)
+                    rc.X = 0;
+                else
+                    rc.X = prc->X - tile_x * This->decode_info.tile_width;
+
+                if (prc->Y < tile_y * This->decode_info.tile_height)
+                    rc.Y = 0;
+                else
+                    rc.Y = prc->Y - tile_y * This->decode_info.tile_height;
+
+                if (prc->X+prc->Width > (tile_x+1) * This->decode_info.tile_width)
+                    rc.Width = This->decode_info.tile_width - rc.X;
+                else
+                    rc.Width = prc->Width + rc.X - prc->X;
+
+                if (prc->Y+prc->Height > (tile_y+1) * This->decode_info.tile_height)
+                    rc.Height = This->decode_info.tile_height - rc.Y;
+                else
+                    rc.Height = prc->Height + rc.Y - prc->Y;
+
+                dst_tilepos = pbBuffer + (cbStride * (rc.Y - prc->Y)) +
+                    ((This->decode_info.bpp * (rc.X - prc->X) + 7) / 8);
+
+                hr = copy_pixels(This->decode_info.bpp, This->cached_tile,
+                    This->decode_info.tile_width, This->decode_info.tile_height, This->decode_info.tile_stride,
+                    &rc, cbStride, cbBufferSize, dst_tilepos);
+            }
+
+            if (FAILED(hr))
+            {
+                LeaveCriticalSection(&This->parent->lock);
+                TRACE("<-- 0x%x\n", hr);
+                return hr;
+            }
+        }
+    }
+
+    LeaveCriticalSection(&This->parent->lock);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI TiffFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface,
+    IWICMetadataQueryReader **ppIMetadataQueryReader)
+{
+    FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface,
+    UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
+{
+    FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface,
+    IWICBitmapSource **ppIThumbnail)
+{
+    FIXME("(%p,%p): stub\n", iface, ppIThumbnail);
+    return E_NOTIMPL;
+}
+
+static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl = {
+    TiffFrameDecode_QueryInterface,
+    TiffFrameDecode_AddRef,
+    TiffFrameDecode_Release,
+    TiffFrameDecode_GetSize,
+    TiffFrameDecode_GetPixelFormat,
+    TiffFrameDecode_GetResolution,
+    TiffFrameDecode_CopyPalette,
+    TiffFrameDecode_CopyPixels,
+    TiffFrameDecode_GetMetadataQueryReader,
+    TiffFrameDecode_GetColorContexts,
+    TiffFrameDecode_GetThumbnail
+};
+
+HRESULT TiffDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
+{
+    HRESULT ret;
+    TiffDecoder *This;
+
+    TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
+
+    *ppv = NULL;
+
+    if (pUnkOuter) return CLASS_E_NOAGGREGATION;
+
+    if (!load_libtiff())
+    {
+        ERR("Failed reading TIFF because unable to load %s\n",SONAME_LIBTIFF);
+        return E_FAIL;
+    }
+
+    This = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffDecoder));
+    if (!This) return E_OUTOFMEMORY;
+
+    This->lpVtbl = &TiffDecoder_Vtbl;
+    This->ref = 1;
+    This->stream = NULL;
+    InitializeCriticalSection(&This->lock);
+    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TiffDecoder.lock");
+    This->tiff = NULL;
+    This->initialized = FALSE;
+
+    ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
+    IUnknown_Release((IUnknown*)This);
+
+    return ret;
+}
+
+#else /* !SONAME_LIBTIFF */
+
+HRESULT TiffDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
+{
+    ERR("Trying to load TIFF picture, but Wine was compiled without TIFF support.\n");
+    return E_FAIL;
+}
+
+#endif
index 632f822..0e72793 100644 (file)
@@ -28,6 +28,7 @@ extern HRESULT BmpEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void**
 extern HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv);
 extern HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
 extern HRESULT JpegDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
+extern HRESULT TiffDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
 
 extern HRESULT PaletteImpl_Create(IWICPalette **palette);
 extern HRESULT StreamImpl_Create(IWICStream **stream);
index 563a7a9..da8e3e4 100644 (file)
@@ -28,6 +28,7 @@
        <file>propertybag.c</file>
        <file>regsvr.c</file>
        <file>stream.c</file>
+       <file>tiffformat.c</file>
        <file>ungif.c</file>
 
        <file>version.rc</file>
index f4b8a0a..6fc8a21 100644 (file)
@@ -102,8 +102,8 @@ static CRITICAL_SECTION_DEBUG WININET_cs_debug =
 static CRITICAL_SECTION WININET_cs = { &WININET_cs_debug, -1, 0, 0, 0, 0 };
 
 static object_header_t **WININET_Handles;
-static UINT WININET_dwNextHandle;
-static UINT WININET_dwMaxHandles;
+static UINT_PTR WININET_dwNextHandle;
+static UINT_PTR WININET_dwMaxHandles;
 
 typedef struct
 {
@@ -122,7 +122,7 @@ static const WCHAR szProxyEnable[] = { 'P','r','o','x','y','E','n','a','b','l','
 HINTERNET WININET_AllocHandle( object_header_t *info )
 {
     object_header_t **p;
-    UINT handle = 0, num;
+    UINT_PTR handle = 0, num;
 
     list_init( &info->children );
 
@@ -173,7 +173,7 @@ object_header_t *WININET_AddRef( object_header_t *info )
 object_header_t *WININET_GetObject( HINTERNET hinternet )
 {
     object_header_t *info = NULL;
-    UINT handle = (UINT) hinternet;
+    UINT_PTR handle = (UINT_PTR) hinternet;
 
     EnterCriticalSection( &WININET_cs );
 
@@ -183,7 +183,7 @@ object_header_t *WININET_GetObject( HINTERNET hinternet )
 
     LeaveCriticalSection( &WININET_cs );
 
-    TRACE("handle %d -> %p\n", handle, info);
+    TRACE("handle %ld -> %p\n", handle, info);
 
     return info;
 }
@@ -218,7 +218,7 @@ BOOL WININET_Release( object_header_t *info )
 BOOL WININET_FreeHandle( HINTERNET hinternet )
 {
     BOOL ret = FALSE;
-    UINT handle = (UINT) hinternet;
+    UINT_PTR handle = (UINT_PTR) hinternet;
     object_header_t *info = NULL, *child, *next;
 
     EnterCriticalSection( &WININET_cs );
@@ -229,7 +229,7 @@ BOOL WININET_FreeHandle( HINTERNET hinternet )
         if( WININET_Handles[handle] )
         {
             info = WININET_Handles[handle];
-            TRACE( "destroying handle %d for object %p\n", handle+1, info);
+            TRACE( "destroying handle %ld for object %p\n", handle+1, info);
             WININET_Handles[handle] = NULL;
             ret = TRUE;
         }
@@ -245,8 +245,8 @@ BOOL WININET_FreeHandle( HINTERNET hinternet )
         /* Free all children as native does */
         LIST_FOR_EACH_ENTRY_SAFE( child, next, &info->children, object_header_t, entry )
         {
-            TRACE( "freeing child handle %d for parent handle %d\n",
-                   (UINT)child->hInternet, handle+1);
+            TRACE( "freeing child handle %ld for parent handle %ld\n",
+                   (UINT_PTR)child->hInternet, handle+1);
             WININET_FreeHandle( child->hInternet );
         }
         WININET_Release( info );
index 29d26ab..6a39c69 100644 (file)
@@ -986,9 +986,9 @@ static DWORD URLCache_CopyEntry(
         ZeroMemory((LPBYTE)lpCacheEntryInfo + dwRequiredSize, 4 - (dwRequiredSize % 4));
     dwRequiredSize = DWORD_ALIGN(dwRequiredSize);
     if (bUnicode)
-        lenUrl = MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, NULL, 0);
+        lenUrl = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, NULL, 0);
     else
-        lenUrl = strlen((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl);
+        lenUrl = strlen((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl);
     dwRequiredSize += (lenUrl + 1) * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
 
     /* FIXME: is source url optional? */
@@ -998,9 +998,9 @@ static DWORD URLCache_CopyEntry(
 
         lpCacheEntryInfo->lpszSourceUrlName = (LPSTR)lpCacheEntryInfo + dwRequiredSize - lenUrlBytes;
         if (bUnicode)
-            MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenUrl + 1);
+            MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenUrl + 1);
         else
-            memcpy(lpCacheEntryInfo->lpszSourceUrlName, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, lenUrlBytes);
+            memcpy(lpCacheEntryInfo->lpszSourceUrlName, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, lenUrlBytes);
     }
 
     if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize))
@@ -1029,7 +1029,7 @@ static DWORD URLCache_CopyEntry(
     if (*lpdwBufferSize >= dwRequiredSize)
     {
         lpCacheEntryInfo->lpHeaderInfo = (LPBYTE)lpCacheEntryInfo + dwRequiredSize - pUrlEntry->dwHeaderInfoSize - 1;
-        memcpy(lpCacheEntryInfo->lpHeaderInfo, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo, pUrlEntry->dwHeaderInfoSize);
+        memcpy(lpCacheEntryInfo->lpHeaderInfo, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo, pUrlEntry->dwHeaderInfoSize);
         ((LPBYTE)lpCacheEntryInfo)[dwRequiredSize - 1] = '\0';
     }
     if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize))
@@ -1041,18 +1041,18 @@ static DWORD URLCache_CopyEntry(
         int lenExtension;
 
         if (bUnicode)
-            lenExtension = MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, NULL, 0);
+            lenExtension = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, NULL, 0);
         else
-            lenExtension = strlen((LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension) + 1;
+            lenExtension = strlen((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension) + 1;
         dwRequiredSize += lenExtension * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
 
         if (*lpdwBufferSize >= dwRequiredSize)
         {
             lpCacheEntryInfo->lpszFileExtension = (LPSTR)lpCacheEntryInfo + dwRequiredSize - lenExtension;
             if (bUnicode)
-                MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenExtension);
+                MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenExtension);
             else
-                memcpy(lpCacheEntryInfo->lpszFileExtension, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, lenExtension * sizeof(CHAR));
+                memcpy(lpCacheEntryInfo->lpszFileExtension, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, lenExtension * sizeof(CHAR));
         }
 
         if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize))
@@ -1175,8 +1175,8 @@ static inline HASH_CACHEFILE_ENTRY * URLCache_HashEntryFromOffset(LPCURLCACHE_HE
 static inline BOOL URLCache_IsHashEntryValid(LPCURLCACHE_HEADER pHeader, const HASH_CACHEFILE_ENTRY *pHashEntry)
 {
     /* check pHashEntry located within acceptable bounds in the URL cache mapping */
-    return ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) >= ENTRY_START_OFFSET) &&
-           ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) < pHeader->dwFileSize);
+    return ((DWORD)((const BYTE*)pHashEntry - (const BYTE*)pHeader) >= ENTRY_START_OFFSET) &&
+           ((DWORD)((const BYTE*)pHashEntry - (const BYTE*)pHeader) < pHeader->dwFileSize);
 }
 
 static BOOL URLCache_FindHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, struct _HASH_ENTRY ** ppHashEntry)
@@ -1557,15 +1557,15 @@ BOOL WINAPI GetUrlCacheEntryInfoA(
     if (pEntry->dwSignature != URL_SIGNATURE)
     {
         URLCacheContainer_UnlockIndex(pContainer, pHeader);
-        FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD)));
+        FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
         SetLastError(ERROR_FILE_NOT_FOUND);
         return FALSE;
     }
 
     pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
-    TRACE("Found URL: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl));
+    TRACE("Found URL: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl));
     if (pUrlEntry->dwOffsetHeaderInfo)
-        TRACE("Header info: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
+        TRACE("Header info: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
 
     if (lpdwCacheEntryInfoBufferSize)
     {
@@ -1639,14 +1639,14 @@ BOOL WINAPI GetUrlCacheEntryInfoW(LPCWSTR lpszUrl,
     if (pEntry->dwSignature != URL_SIGNATURE)
     {
         URLCacheContainer_UnlockIndex(pContainer, pHeader);
-        FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD)));
+        FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
         SetLastError(ERROR_FILE_NOT_FOUND);
         return FALSE;
     }
 
     pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
-    TRACE("Found URL: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl));
-    TRACE("Header info: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
+    TRACE("Found URL: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl));
+    TRACE("Header info: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
 
     if (lpdwCacheEntryInfoBufferSize)
     {
@@ -3265,9 +3265,9 @@ BOOL WINAPI FindNextUrlCacheEntryA(
                 if (pEntry->dwSignature != URL_SIGNATURE)
                     continue;
 
-                pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
-                TRACE("Found URL: %s\n", (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl);
-                TRACE("Header info: %s\n", (LPBYTE)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo);
+                pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
+                TRACE("Found URL: %s\n", (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetUrl);
+                TRACE("Header info: %s\n", (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo);
 
                 error = URLCache_CopyEntry(
                     pContainer,
@@ -3563,7 +3563,7 @@ BOOL WINAPI IsUrlCacheEntryExpiredA( LPCSTR url, DWORD dwFlags, FILETIME* pftLas
     if (pEntry->dwSignature != URL_SIGNATURE)
     {
         URLCacheContainer_UnlockIndex(pContainer, pHeader);
-        FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD)));
+        FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
         SetLastError(ERROR_FILE_NOT_FOUND);
         return FALSE;
     }
@@ -3625,7 +3625,7 @@ BOOL WINAPI IsUrlCacheEntryExpiredW( LPCWSTR url, DWORD dwFlags, FILETIME* pftLa
     if (pEntry->dwSignature != URL_SIGNATURE)
     {
         URLCacheContainer_UnlockIndex(pContainer, pHeader);
-        FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD)));
+        FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
         SetLastError(ERROR_FILE_NOT_FOUND);
         return FALSE;
     }
index 69c9dd3..8659266 100644 (file)
@@ -1348,7 +1348,7 @@ static BOOL CRYPT_AsnDecodeSPCLinkInternal(DWORD dwCertEncodingType,
                     link->dwLinkChoice = SPC_FILE_LINK_CHOICE;
                     for (i = 0; i < dataLen / sizeof(WCHAR); i++)
                         link->u.pwszFile[i] =
-                         hton16(*(WORD *)(ptr + i * sizeof(WCHAR)));
+                         hton16(*(const WORD *)(ptr + i * sizeof(WCHAR)));
                     link->u.pwszFile[realDataLen / sizeof(WCHAR)] = '\0';
                     TRACE("returning file %s\n", debugstr_w(link->u.pwszFile));
                 }
index bb89ead..fee4f03 100644 (file)
@@ -640,7 +640,199 @@ void free_servent(struct servent* s)
     HFREE(s);
 }
 
+/* This function is far from perfect but it works enough */
+static
+LPHOSTENT
+FindEntryInHosts(IN CONST CHAR FAR* name)
+{
+    BOOL Found = FALSE;
+    HANDLE HostsFile;
+    CHAR HostsDBData[BUFSIZ] = { 0 };
+    PCHAR SystemDirectory = HostsDBData;
+    PCHAR HostsLocation = "\\drivers\\etc\\hosts";
+    PCHAR AddressStr, DnsName = NULL, AddrTerm, NameSt, NextLine, ThisLine, Comment;
+    UINT SystemDirSize = sizeof(HostsDBData) - 1, ValidData = 0;
+    DWORD ReadSize;
+    ULONG Address;
+    PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
+
+    /* We assume that the parameters are valid */
+
+    if (!GetSystemDirectoryA(SystemDirectory, SystemDirSize))
+    {
+        WSASetLastError(WSANO_RECOVERY);
+        WS_DbgPrint(MIN_TRACE, ("Could not get windows system directory.\n"));
+        return NULL; /* Can't get system directory */
+    }
+
+    strncat(SystemDirectory,
+            HostsLocation,
+            SystemDirSize );
+
+    HostsFile = CreateFileA(SystemDirectory,
+                            GENERIC_READ,
+                            FILE_SHARE_READ,
+                            NULL,
+                            OPEN_EXISTING,
+                            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
+                            NULL);
+    if (HostsFile == INVALID_HANDLE_VALUE)
+    {
+        WSASetLastError(WSANO_RECOVERY);
+        return NULL;
+    }
+
+    while(!Found &&
+          ReadFile(HostsFile,
+                   HostsDBData + ValidData,
+                   sizeof(HostsDBData) - ValidData,
+                   &ReadSize,
+                   NULL))
+    {
+        ValidData += ReadSize;
+        ReadSize = 0;
+        NextLine = ThisLine = HostsDBData;
+
+        /* Find the beginning of the next line */
+        while(NextLine < HostsDBData + ValidData &&
+              *NextLine != '\r' && *NextLine != '\n' )
+        {
+            NextLine++;
+        }
+
+        /* Zero and skip, so we can treat what we have as a string */
+        if( NextLine > HostsDBData + ValidData )
+            break;
+
+        *NextLine = 0; NextLine++;
+
+        Comment = strchr( ThisLine, '#' );
+        if( Comment ) *Comment = 0; /* Terminate at comment start */
+
+        AddressStr = ThisLine;
+        /* Find the first space separating the IP address from the DNS name */
+        AddrTerm = strchr(ThisLine, ' ');
+        if (AddrTerm)
+        {
+           /* Terminate the address string */
+           *AddrTerm = 0;
 
+           /* Find the last space before the DNS name */
+           NameSt = strrchr(ThisLine, ' ');
+
+           /* If there is only one space (the one we removed above), then just use the address terminator */
+           if (!NameSt)
+               NameSt = AddrTerm;
+
+           /* Move from the space to the first character of the DNS name */
+           NameSt++;
+
+           DnsName = NameSt;
+
+           if (!strcmp(name, DnsName))
+           {
+               Found = TRUE;
+               break;
+           }
+        }
+
+        /* Get rid of everything we read so far */
+        while( NextLine <= HostsDBData + ValidData &&
+               isspace (*NextLine))
+        {
+            NextLine++;
+        }
+
+        if (HostsDBData + ValidData - NextLine <= 0)
+            break;
+
+        WS_DbgPrint(MAX_TRACE,("About to move %d chars\n",
+                    HostsDBData + ValidData - NextLine));
+
+        memmove(HostsDBData,
+                NextLine,
+                HostsDBData + ValidData - NextLine );
+        ValidData -= NextLine - HostsDBData;
+        WS_DbgPrint(MAX_TRACE,("Valid bytes: %d\n", ValidData));
+    }
+
+    CloseHandle(HostsFile);
+
+    if (!Found)
+    {
+        WS_DbgPrint(MAX_TRACE,("Not found\n"));
+        WSASetLastError(WSANO_DATA);
+        return NULL;
+    }
+
+    if( !p->Hostent )
+    {
+        p->Hostent = HeapAlloc(GlobalHeap, 0, sizeof(*p->Hostent));
+        if( !p->Hostent )
+        {
+            WSASetLastError( WSATRY_AGAIN );
+            return NULL;
+        }
+    }
+
+    p->Hostent->h_name = HeapAlloc(GlobalHeap, 0, strlen(DnsName));
+    if( !p->Hostent->h_name )
+    {
+        WSASetLastError( WSATRY_AGAIN );
+        return NULL;
+    }
+
+    RtlCopyMemory(p->Hostent->h_name,
+                  DnsName,
+                  strlen(DnsName));
+
+    p->Hostent->h_aliases = HeapAlloc(GlobalHeap, 0, sizeof(char *));
+    if( !p->Hostent->h_aliases )
+    {
+        WSASetLastError( WSATRY_AGAIN );
+        return NULL;
+    }
+
+    p->Hostent->h_aliases[0] = 0;
+
+    if (strstr(AddressStr, ":"))
+    {
+       DbgPrint("AF_INET6 NOT SUPPORTED!\n");
+       WSASetLastError(WSAEINVAL);
+       return NULL;
+    }
+    else
+       p->Hostent->h_addrtype = AF_INET;
+
+    p->Hostent->h_addr_list = HeapAlloc(GlobalHeap, 0, sizeof(char *));
+    if( !p->Hostent->h_addr_list )
+    {
+        WSASetLastError( WSATRY_AGAIN );
+        return NULL;
+    }
+
+    Address = inet_addr(AddressStr);
+    if (Address == INADDR_NONE)
+    {
+        WSASetLastError(WSAEINVAL);
+        return NULL;
+    }
+
+    p->Hostent->h_addr_list[0] = HeapAlloc(GlobalHeap, 0, sizeof(Address));
+    if( !p->Hostent->h_addr_list[0] )
+    {
+        WSASetLastError( WSATRY_AGAIN );
+        return NULL;
+    }
+
+    RtlCopyMemory(p->Hostent->h_addr_list[0],
+                  &Address,
+                  sizeof(Address));
+
+    p->Hostent->h_length = sizeof(Address);
+
+    return p->Hostent;
+}
 
 LPHOSTENT
 EXPORT
@@ -661,6 +853,7 @@ gethostbyname(IN  CONST CHAR FAR* name)
     /* include/WinDNS.h -- look up DNS_RECORD on MSDN */
     PDNS_RECORD dp = 0;
     PWINSOCK_THREAD_BLOCK p;
+    LPHOSTENT Hostent;
 
     addr = GH_INVALID;
 
@@ -726,6 +919,12 @@ gethostbyname(IN  CONST CHAR FAR* name)
         case GH_RFC1123_DNS:
         /* DNS_TYPE_A: include/WinDNS.h */
         /* DnsQuery -- lib/dnsapi/dnsapi/query.c */
+
+        /* Look for the DNS name in the hosts file */
+        Hostent = FindEntryInHosts(name);
+        if (Hostent)
+           return Hostent;
+
         dns_status = DnsQuery_A(name,
                                 DNS_TYPE_A,
                                 DNS_QUERY_STANDARD,
@@ -993,7 +1192,7 @@ getservbyname(IN  CONST CHAR FAR* name,
         }
 
         /* Zero and skip, so we can treat what we have as a string */
-        if( NextLine >= ServiceDBData + ValidData )
+        if( NextLine > ServiceDBData + ValidData )
             break;
 
         *NextLine = 0; NextLine++;
@@ -1174,7 +1373,7 @@ getservbyport(IN  INT port,
                *NextLine != '\r' && *NextLine != '\n' ) NextLine++;
 
         /* Zero and skip, so we can treat what we have as a string */
-        if( NextLine >= ServiceDBData + ValidData )
+        if( NextLine > ServiceDBData + ValidData )
             break;
 
         *NextLine = 0; NextLine++;
index c3e5b7d..334cdfc 100644 (file)
@@ -10,7 +10,7 @@
 <directory name="compbatt">
        <xi:include href="compbatt/compbatt.rbuild" />
 </directory>
-</group>
+
 
 <module name="acpi" type="kernelmodedriver" installbase="system32/drivers" installname="acpi.sys" allowwarnings="true">
        <bootstrap installbase="$(CDOUTPUT)" />
@@ -36,3 +36,4 @@
        <file>buspdo.c</file>
        <file>main.c</file>
 </module>
+</group>
index 11a8fbe..fc752ff 100644 (file)
@@ -13,4 +13,7 @@
 <directory name="pcix">
        <xi:include href="pcix/pcix.rbuild" />
 </directory>
+<directory name="pcmcia">
+       <xi:include href="pcmcia/pcmcia.rbuild" />
+</directory>
 </group>
diff --git a/drivers/bus/isapnp/fdo.c b/drivers/bus/isapnp/fdo.c
new file mode 100644 (file)
index 0000000..51a0f4b
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * PROJECT:         ReactOS ISA PnP Bus driver
+ * FILE:            fdo.c
+ * PURPOSE:         FDO-specific code
+ * PROGRAMMERS:     Cameron Gutman (cameron.gutman@reactos.org)
+ */
+#include <isapnp.h>
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS
+NTAPI
+IsaFdoStartDevice(
+  IN PISAPNP_FDO_EXTENSION FdoExt,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp)
+{
+  NTSTATUS Status;
+  KIRQL OldIrql;
+
+  KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
+
+  Status = IsaHwDetectReadDataPort(FdoExt);
+  if (!NT_SUCCESS(Status))
+  {
+      KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
+      return Status;
+  }
+
+  FdoExt->Common.State = dsStarted;
+
+  KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
+
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IsaFdoQueryDeviceRelations(
+  IN PISAPNP_FDO_EXTENSION FdoExt,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp)
+{
+  NTSTATUS Status;
+  PLIST_ENTRY CurrentEntry;
+  PISAPNP_LOGICAL_DEVICE IsaDevice;
+  PDEVICE_RELATIONS DeviceRelations;
+  KIRQL OldIrql;
+  ULONG i = 0;
+
+  if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
+      return Irp->IoStatus.Status;
+
+  KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
+
+  Status = IsaHwFillDeviceList(FdoExt);
+  if (!NT_SUCCESS(Status))
+  {
+      KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
+      return Status;
+  }
+
+  DeviceRelations = ExAllocatePool(NonPagedPool,
+                            sizeof(DEVICE_RELATIONS) + sizeof(DEVICE_OBJECT) * (FdoExt->DeviceCount - 1));
+  if (!DeviceRelations)
+  {
+      KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
+      return STATUS_INSUFFICIENT_RESOURCES;
+  }
+
+  CurrentEntry = FdoExt->DeviceListHead.Flink;
+  while (CurrentEntry != &FdoExt->DeviceListHead)
+  {
+     IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, ListEntry);
+
+     DeviceRelations->Objects[i++] = IsaDevice->Common.Self;
+
+     ObReferenceObject(IsaDevice->Common.Self);
+
+     CurrentEntry = CurrentEntry->Flink;
+  }
+
+  DeviceRelations->Count = FdoExt->DeviceCount;
+
+  KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
+
+  Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
+
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IsaFdoPnp(
+  IN PISAPNP_FDO_EXTENSION FdoExt,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp)
+{
+  NTSTATUS Status = Irp->IoStatus.Status;
+
+  switch (IrpSp->MinorFunction)
+  {
+     case IRP_MN_START_DEVICE:
+       Status = IsaForwardIrpSynchronous(FdoExt, Irp);
+
+       if (NT_SUCCESS(Status))
+         Status = IsaFdoStartDevice(FdoExt, Irp, IrpSp);
+
+       Irp->IoStatus.Status = Status;
+
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return Status;
+
+     case IRP_MN_STOP_DEVICE:
+       FdoExt->Common.State = dsStopped;
+
+       Status = STATUS_SUCCESS;
+       break;
+
+     case IRP_MN_QUERY_DEVICE_RELATIONS:
+       Status = IsaFdoQueryDeviceRelations(FdoExt, Irp, IrpSp);
+
+       Irp->IoStatus.Status = Status;
+
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return Status;
+
+     case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
+       DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
+       break;
+
+     default:
+       DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction);
+       break;
+  }
+
+  IoSkipCurrentIrpStackLocation(Irp);
+
+  return IoCallDriver(FdoExt->Ldo, Irp);
+}
diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c
new file mode 100644 (file)
index 0000000..99e5d44
--- /dev/null
@@ -0,0 +1,579 @@
+/*
+ * PROJECT:         ReactOS ISA PnP Bus driver
+ * FILE:            hardware.c
+ * PURPOSE:         Hardware support code
+ * PROGRAMMERS:     Cameron Gutman (cameron.gutman@reactos.org)
+ */
+#include <isapnp.h>
+#include <isapnphw.h>
+
+#define NDEBUG
+#include <debug.h>
+
+static
+inline
+VOID
+WriteAddress(USHORT Address)
+{
+  WRITE_PORT_UCHAR((PUCHAR)ISAPNP_ADDRESS, Address);
+}
+
+static
+inline
+VOID
+WriteData(USHORT Data)
+{
+  WRITE_PORT_UCHAR((PUCHAR)ISAPNP_WRITE_DATA, Data);
+}
+
+static
+inline
+UCHAR
+ReadData(PUCHAR ReadDataPort)
+{
+  return READ_PORT_UCHAR(ReadDataPort);
+}
+
+static
+inline
+VOID
+WriteByte(USHORT Address, USHORT Value)
+{
+  WriteAddress(Address);
+  WriteData(Value);
+}
+
+static
+inline
+UCHAR
+ReadByte(PUCHAR ReadDataPort, USHORT Address)
+{
+  WriteAddress(Address);
+  return ReadData(ReadDataPort);
+}
+
+static
+inline
+USHORT
+ReadWord(PUCHAR ReadDataPort, USHORT Address)
+{
+  return ((ReadByte(ReadDataPort, Address) << 8) |
+          (ReadByte(ReadDataPort, Address + 1)));
+}
+
+static
+inline
+VOID
+SetReadDataPort(PUCHAR ReadDataPort)
+{
+  WriteByte(ISAPNP_READPORT, ((ULONG_PTR)ReadDataPort >> 2));
+}
+
+static
+inline
+VOID
+EnterIsolationState(VOID)
+{
+  WriteAddress(ISAPNP_SERIALISOLATION);
+}
+
+static
+inline
+VOID
+WaitForKey(VOID)
+{
+  WriteByte(ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_WAIT_FOR_KEY);
+}
+
+static
+inline
+VOID
+ResetCsn(VOID)
+{
+  WriteByte(ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_RESET_CSN);
+}
+
+static
+inline
+VOID
+Wake(USHORT Csn)
+{
+  WriteByte(ISAPNP_WAKE, Csn);
+}
+
+static
+inline
+USHORT
+ReadResourceData(PUCHAR ReadDataPort)
+{
+  return ReadByte(ReadDataPort, ISAPNP_RESOURCEDATA);
+}
+
+static
+inline
+USHORT
+ReadStatus(PUCHAR ReadDataPort)
+{
+  return ReadByte(ReadDataPort, ISAPNP_STATUS);
+}
+
+static
+inline
+VOID
+WriteCsn(USHORT Csn)
+{
+  WriteByte(ISAPNP_CARDSELECTNUMBER, Csn);
+}
+
+static
+inline
+VOID
+WriteLogicalDeviceNumber(USHORT LogDev)
+{
+  WriteByte(ISAPNP_LOGICALDEVICENUMBER, LogDev);
+}
+
+static
+inline
+VOID
+ActivateDevice(USHORT LogDev)
+{
+  WriteLogicalDeviceNumber(LogDev);
+  WriteByte(ISAPNP_ACTIVATE, 1);
+}
+
+static
+inline
+VOID
+DeactivateDevice(USHORT LogDev)
+{
+  WriteLogicalDeviceNumber(LogDev);
+  WriteByte(ISAPNP_ACTIVATE, 0);
+}
+
+static
+inline
+USHORT
+ReadIoBase(PUCHAR ReadDataPort, USHORT Index)
+{
+  return ReadWord(ReadDataPort, ISAPNP_IOBASE(Index));
+}
+
+static
+inline
+USHORT
+ReadIrqNo(PUCHAR ReadDataPort, USHORT Index)
+{
+  return ReadByte(ReadDataPort, ISAPNP_IRQNO(Index));
+}
+
+static
+inline
+VOID
+HwDelay(VOID)
+{
+  KeStallExecutionProcessor(1000);
+}
+
+static
+inline
+USHORT
+NextLFSR(USHORT Lfsr, USHORT InputBit)
+{
+  ULONG NextLfsr = Lfsr >> 1;
+
+  NextLfsr |= (((Lfsr ^ NextLfsr) ^ InputBit)) << 7;
+
+  return NextLfsr;
+}
+
+static
+VOID
+SendKey(VOID)
+{
+  USHORT i, Lfsr;
+
+  HwDelay();
+  WriteAddress(0x00);
+  WriteAddress(0x00);
+
+  Lfsr = ISAPNP_LFSR_SEED;
+  for (i = 0; i < 32; i++)
+  {
+    WriteAddress(Lfsr);
+    Lfsr = NextLFSR(Lfsr, 0);
+  }
+}
+
+static
+USHORT
+PeekByte(PUCHAR ReadDataPort)
+{
+  USHORT i;
+
+  for (i = 0; i < 20; i++)
+  {
+    if (ReadStatus(ReadDataPort) & 0x01)
+      return ReadResourceData(ReadDataPort);
+
+    HwDelay();
+  }
+
+  return 0xFF;
+}
+
+static
+VOID
+Peek(PUCHAR ReadDataPort, PVOID Buffer, ULONG Length)
+{
+  USHORT i, byte;
+
+  for (i = 0; i < Length; i++)
+  {
+    byte = PeekByte(ReadDataPort);
+    if (Buffer)
+       *((PUCHAR)Buffer + i) = byte;
+  }
+}
+
+static
+USHORT
+IsaPnpChecksum(PISAPNP_IDENTIFIER Identifier)
+{
+  USHORT i,j, Lfsr, Byte;
+
+  Lfsr = ISAPNP_LFSR_SEED;
+  for (i = 0; i < 8; i++)
+  {
+    Byte = *(((PUCHAR)Identifier) + i);
+    for (j = 0; j < 8; j++)
+    {
+      Lfsr = NextLFSR(Lfsr, Byte);
+      Byte >>= 1;
+    }
+  }
+
+  return Lfsr;
+}
+
+static
+BOOLEAN
+FindTag(PUCHAR ReadDataPort, USHORT WantedTag, PVOID Buffer, ULONG Length)
+{
+  USHORT Tag, TagLen;
+
+  do
+  {
+    Tag = PeekByte(ReadDataPort);
+    if (ISAPNP_IS_SMALL_TAG(Tag))
+    {
+      TagLen = ISAPNP_SMALL_TAG_LEN(Tag);
+      Tag = ISAPNP_SMALL_TAG_NAME(Tag);
+    }
+    else
+    {
+      TagLen = PeekByte(ReadDataPort) + (PeekByte(ReadDataPort) << 8);
+      Tag = ISAPNP_LARGE_TAG_NAME(Tag);
+    }
+
+    if (Tag == WantedTag)
+    {
+      if (Length > TagLen)
+          Length = TagLen;
+
+      Peek(ReadDataPort, Buffer, Length);
+
+      return TRUE;
+    }
+    else
+    {
+      Peek(ReadDataPort, NULL, Length);
+    }
+  } while (Tag != ISAPNP_TAG_END);
+
+  return FALSE;
+}
+
+static
+BOOLEAN
+FindLogDevId(PUCHAR ReadDataPort, USHORT LogDev, PISAPNP_LOGDEVID LogDeviceId)
+{
+  USHORT i;
+
+  for (i = 0; i <= LogDev; i++)
+  {
+    if (!FindTag(ReadDataPort, ISAPNP_TAG_LOGDEVID, LogDeviceId, sizeof(*LogDeviceId)))
+        return FALSE;
+  }
+
+  return TRUE;
+}
+
+static
+INT
+TryIsolate(PUCHAR ReadDataPort)
+{
+  ISAPNP_IDENTIFIER Identifier;
+  USHORT i, j;
+  BOOLEAN Seen55aa, SeenLife;
+  INT Csn = 0;
+  USHORT Byte, Data;
+
+  DPRINT("Setting read data port: 0x%x\n", ReadDataPort);
+
+  WaitForKey();
+  SendKey();
+
+  ResetCsn();
+  HwDelay();
+  HwDelay();
+
+  WaitForKey();
+  SendKey();
+  Wake(0x00);
+
+  SetReadDataPort(ReadDataPort);
+  HwDelay();
+
+  while (TRUE)
+  {
+    EnterIsolationState();
+    HwDelay();
+
+    RtlZeroMemory(&Identifier, sizeof(Identifier));
+
+    Seen55aa = SeenLife = FALSE;
+    for (i = 0; i < 9; i++)
+    {
+      Byte = 0;
+      for (j = 0; j < 8; j++)
+      {
+        Data = ReadData(ReadDataPort);
+        HwDelay();
+        Data = ((Data << 8) | ReadData(ReadDataPort));
+        HwDelay();
+        Byte >>= 1;
+
+        if (Data != 0xFFFF)
+        {
+           SeenLife = TRUE;
+           if (Data == 0x55AA)
+           {
+             Byte |= 0x80;
+             Seen55aa = TRUE;
+           }
+        }
+      }
+      *(((PUCHAR)&Identifier) + i) = Byte;
+    }
+
+    if (!Seen55aa)
+    {
+       if (Csn)
+       {
+         DPRINT("Found no more cards\n");
+       }
+       else
+       {
+         if (SeenLife)
+         {
+           DPRINT("Saw life but no cards, trying new read port\n");
+           Csn = -1;
+         }
+         else
+         {
+           DPRINT("Saw no sign of life, abandoning isolation\n");
+         }
+       }
+       break;
+    }
+
+    if (Identifier.Checksum != IsaPnpChecksum(&Identifier))
+    {
+        DPRINT("Bad checksum, trying next read data port\n");
+        Csn = -1;
+        break;
+    }
+
+    Csn++;
+
+    WriteCsn(Csn);
+    HwDelay();
+
+    Wake(0x00);
+    HwDelay();
+  }
+
+  WaitForKey();
+
+  if (Csn > 0)
+  {
+    DPRINT("Found %d cards at read port 0x%x\n", Csn, ReadDataPort);
+  }
+
+  return Csn;
+}
+
+static
+PUCHAR
+Isolate(VOID)
+{
+  PUCHAR ReadPort;
+
+  for (ReadPort = (PUCHAR)ISAPNP_READ_PORT_START;
+       (ULONG_PTR)ReadPort <= ISAPNP_READ_PORT_MAX;
+       ReadPort += ISAPNP_READ_PORT_STEP)
+  {
+    /* Avoid the NE2000 probe space */
+    if ((ULONG_PTR)ReadPort >= 0x280 &&
+        (ULONG_PTR)ReadPort <= 0x380)
+        continue;
+
+    if (TryIsolate(ReadPort) > 0)
+        return ReadPort;
+  }
+
+  return 0;
+}
+
+VOID
+DeviceActivation(PISAPNP_LOGICAL_DEVICE IsaDevice,
+                 BOOLEAN Activate)
+{
+  WaitForKey();
+  SendKey();
+  Wake(IsaDevice->CSN);
+
+  if (Activate)
+    ActivateDevice(IsaDevice->LDN);
+  else
+    DeactivateDevice(IsaDevice->LDN);
+
+  HwDelay();
+
+  WaitForKey();
+}
+
+NTSTATUS
+ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
+{
+  PISAPNP_LOGICAL_DEVICE LogDevice;
+  ISAPNP_IDENTIFIER Identifier;
+  ISAPNP_LOGDEVID LogDevId;
+  USHORT Csn;
+  USHORT LogDev;
+  PDEVICE_OBJECT Pdo;
+  NTSTATUS Status;
+
+  ASSERT(FdoExt->ReadDataPort);
+
+  for (Csn = 1; Csn <= 0xFF; Csn++)
+  {
+    for (LogDev = 0; LogDev <= 0xFF; LogDev++)
+    {
+      Status = IoCreateDevice(FdoExt->Common.Self->DriverObject,
+                              sizeof(ISAPNP_LOGICAL_DEVICE),
+                              NULL,
+                              FILE_DEVICE_CONTROLLER,
+                              FILE_DEVICE_SECURE_OPEN,
+                              FALSE,
+                              &Pdo);
+      if (!NT_SUCCESS(Status))
+          return Status;
+
+      Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
+
+      LogDevice = Pdo->DeviceExtension;
+
+      RtlZeroMemory(LogDevice, sizeof(ISAPNP_LOGICAL_DEVICE));
+
+      LogDevice->Common.Self = Pdo;
+      LogDevice->Common.IsFdo = FALSE;
+      LogDevice->Common.State = dsStopped;
+
+      LogDevice->CSN = Csn;
+      LogDevice->LDN = LogDev;
+
+      WaitForKey();
+      SendKey();
+      Wake(Csn);
+
+      Peek(FdoExt->ReadDataPort, &Identifier, sizeof(Identifier));
+
+      if (Identifier.VendorId & 0x80)
+      {
+          IoDeleteDevice(LogDevice->Common.Self);
+          return STATUS_SUCCESS;
+      }
+
+      if (!FindLogDevId(FdoExt->ReadDataPort, LogDev, &LogDevId))
+          break;
+
+      WriteLogicalDeviceNumber(LogDev);
+
+      LogDevice->VendorId = LogDevId.VendorId;
+      LogDevice->ProdId = LogDevId.ProdId;
+      LogDevice->IoAddr = ReadIoBase(FdoExt->ReadDataPort, 0);
+      LogDevice->IrqNo = ReadIrqNo(FdoExt->ReadDataPort, 0);
+
+      DPRINT1("Detected ISA PnP device - VID: 0x%x PID: 0x%x IoBase: 0x%x IRQ:0x%x\n",
+               LogDevice->VendorId, LogDevice->ProdId, LogDevice->IoAddr, LogDevice->IrqNo);
+
+      WaitForKey();
+
+      Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+      InsertTailList(&FdoExt->DeviceListHead, &LogDevice->ListEntry);
+      FdoExt->DeviceCount++;
+    }
+  }
+
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IsaHwDetectReadDataPort(
+  IN PISAPNP_FDO_EXTENSION FdoExt)
+{
+  FdoExt->ReadDataPort = Isolate();
+  if (!FdoExt->ReadDataPort)
+  {
+      DPRINT1("No read data port found\n");
+      return STATUS_UNSUCCESSFUL;
+  }
+
+  DPRINT1("Detected read data port at 0x%x\n", FdoExt->ReadDataPort);
+
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IsaHwActivateDevice(
+  IN PISAPNP_LOGICAL_DEVICE LogicalDevice)
+{
+  DeviceActivation(LogicalDevice,
+                   TRUE);
+
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IsaHwDeactivateDevice(
+  IN PISAPNP_LOGICAL_DEVICE LogicalDevice)
+{
+  DeviceActivation(LogicalDevice,
+                   FALSE);
+
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IsaHwFillDeviceList(
+  IN PISAPNP_FDO_EXTENSION FdoExt)
+{
+  return ProbeIsaPnpBus(FdoExt);
+}
index 37262c3..594b5a9 100644 (file)
-/* $Id$
- *
- * PROJECT:         ReactOS ISA PnP Bus driver
- * FILE:            isapnp.c
- * PURPOSE:         Driver entry
- * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
- * NOTE:            Parts adapted from linux ISA PnP driver
- * UPDATE HISTORY:
- *      01-05-2001  CSH  Created
- */
-#include <isapnp.h>
-
-#ifndef NDEBUG
-#define NDEBUG
-#endif
-#include <debug.h>
-
-
-#ifdef  ALLOC_PRAGMA
-
-// Make the initialization routines discardable, so that they
-// don't waste space
-
-#pragma  alloc_text(init, DriverEntry)
-
-
-#endif  /*  ALLOC_PRAGMA  */
-
-
-PUCHAR IsaPnPReadPort;
-
-
-#define UCHAR2USHORT(v0, v1) \
-  ((v1 << 8) | v0)
-
-#define UCHAR2ULONG(v0, v1, v2, v3) \
-  ((UCHAR2USHORT(v2, v3) << 16) | UCHAR2USHORT(v0, v1))
-
-
-#ifndef NDEBUG
-
-struct
-{
-  PCH Name;
-} SmallTags[] = {
-  {"Unknown Small Tag"},
-  {"ISAPNP_SRIN_VERSION"},
-  {"ISAPNP_SRIN_LDEVICE_ID"},
-  {"ISAPNP_SRIN_CDEVICE_ID"},
-  {"ISAPNP_SRIN_IRQ_FORMAT"},
-  {"ISAPNP_SRIN_DMA_FORMAT"},
-  {"ISAPNP_SRIN_START_DFUNCTION"},
-  {"ISAPNP_SRIN_END_DFUNCTION"},
-  {"ISAPNP_SRIN_IO_DESCRIPTOR"},
-  {"ISAPNP_SRIN_FL_IO_DESCRIPOTOR"},
-  {"Reserved Small Tag"},
-  {"Reserved Small Tag"},
-  {"Reserved Small Tag"},
-  {"Reserved Small Tag"},
-  {"ISAPNP_SRIN_VENDOR_DEFINED"},
-  {"ISAPNP_SRIN_END_TAG"}
-};
-
-struct
-{
-  PCH Name;
-} LargeTags[] = {
-  {"Unknown Large Tag"},
-  {"ISAPNP_LRIN_MEMORY_RANGE"},
-  {"ISAPNP_LRIN_ID_STRING_ANSI"},
-  {"ISAPNP_LRIN_ID_STRING_UNICODE"},
-  {"ISAPNP_LRIN_VENDOR_DEFINED"},
-  {"ISAPNP_LRIN_MEMORY_RANGE32"},
-  {"ISAPNP_LRIN_FL_MEMORY_RANGE32"}
-};
-
-PCSZ TagName(ULONG Tag, BOOLEAN Small)
-{
-  if (Small && (Tag <= ISAPNP_SRIN_END_TAG)) {
-    return SmallTags[Tag].Name;
-  } else if (Tag <= ISAPNP_LRIN_FL_MEMORY_RANGE32){
-    return LargeTags[Tag].Name;
-  }
-
-  return NULL;
-}
-
-#endif
-
-static __inline VOID WriteData(UCHAR Value)
-{
-  WRITE_PORT_UCHAR((PUCHAR)ISAPNP_WRITE_PORT, Value);
-}
-
-static __inline VOID WriteAddress(UCHAR Value)
-{
-       WRITE_PORT_UCHAR((PUCHAR)ISAPNP_ADDRESS_PORT, Value);
-       KeStallExecutionProcessor(20);
-}
-
-static __inline UCHAR ReadData(VOID)
-{
-       return READ_PORT_UCHAR(IsaPnPReadPort);
-}
-
-static UCHAR ReadUchar(UCHAR Index)
-{
-       WriteAddress(Index);
-       return ReadData();
-}
-
-#if 0
-static USHORT ReadUshort(UCHAR Index)
-{
-       USHORT Value;
-
-       Value = ReadUchar(Index);
-       Value = (Value << 8) + ReadUchar(Index + 1);
-       return Value;
-}
-
-static ULONG ReadUlong(UCHAR Index)
-{
-       ULONG Value;
-
-       Value = ReadUchar(Index);
-       Value = (Value << 8) + ReadUchar(Index + 1);
-       Value = (Value << 8) + ReadUchar(Index + 2);
-       Value = (Value << 8) + ReadUchar(Index + 3);
-       return Value;
-}
-#endif
-
-static VOID WriteUchar(UCHAR Index, UCHAR Value)
-{
-       WriteAddress(Index);
-       WriteData(Value);
-}
-
-#if 0
-static VOID WriteUshort(UCHAR Index, USHORT Value)
-{
-       WriteUchar(Index, Value >> 8);
-       WriteUchar(Index + 1, Value);
-}
-
-static VOID WriteUlong(UCHAR Index, ULONG Value)
-{
-       WriteUchar(Index, Value >> 24);
-       WriteUchar(Index + 1, Value >> 16);
-       WriteUchar(Index + 2, Value >> 8);
-       WriteUchar(Index + 3, Value);
-}
-#endif
-
-static __inline VOID SetReadDataPort(ULONG_PTR Port)
-{
-  IsaPnPReadPort = (PUCHAR)Port;
-       WriteUchar(0x00, (UCHAR) (Port >> 2));
-       KeStallExecutionProcessor(100);
-}
-
-static VOID SendKey(VOID)
-{
-  ULONG i;
-  UCHAR msb;
-       UCHAR code;
-
-  /* FIXME: Is there something better? */
-       KeStallExecutionProcessor(1000);
-       WriteAddress(0x00);
-       WriteAddress(0x00);
-
-  code = 0x6a;
-       WriteAddress(code);
-       for (i = 1; i < 32; i++) {
-               msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
-               code = (code >> 1) | msb;
-               WriteAddress(code);
-       }
-}
-
-/* Place all PnP cards in wait-for-key state */
-static VOID SendWait(VOID)
-{
-       WriteUchar(0x02, 0x02);
-}
-
-static VOID SendWake(UCHAR csn)
-{
-       WriteUchar(ISAPNP_CARD_WAKECSN, csn);
-}
-
-#if 0
-static VOID SelectLogicalDevice(UCHAR LogicalDevice)
-{
-       WriteUchar(ISAPNP_CARD_LOG_DEVICE_NUM, LogicalDevice);
-}
-
-static VOID ActivateLogicalDevice(UCHAR LogicalDevice)
-{
-       SelectLogicalDevice(LogicalDevice);
-       WriteUchar(ISAPNP_CONTROL_ACTIVATE, 0x1);
-       KeStallExecutionProcessor(250);
-}
-
-static VOID DeactivateLogicalDevice(UCHAR LogicalDevice)
-{
-       SelectLogicalDevice(LogicalDevice);
-       WriteUchar(ISAPNP_CONTROL_ACTIVATE, 0x0);
-       KeStallExecutionProcessor(500);
-}
-#endif
-
-#define READ_DATA_PORT_STEP 32  /* Minimum is 4 */
-
-static ULONG_PTR FindNextReadPort(VOID)
-{
-       ULONG_PTR Port;
-
-
-
-       Port = (ULONG_PTR)IsaPnPReadPort;
-
-       while (TRUE) {
-
-               Port += READ_DATA_PORT_STEP;
-
-
-
-               if (Port > ISAPNP_MAX_READ_PORT)
-
-               {
-
-                       return 0;
-
-               }
-
-
-
-               /*
-
-                * We cannot use NE2000 probe spaces for
-
-                * ISAPnP or we will lock up machines
-
-                */
-
-               if ((Port < 0x280) || (Port > 0x380))
-
-               {
-
-                       return Port;
-
-               }
-
-       }
-
-}
-
-static BOOLEAN IsolateReadDataPortSelect(VOID)
-{
-  ULONG_PTR Port;
-
-       SendWait();
-       SendKey();
-
-       /* Control: reset CSN and conditionally everything else too */
-       WriteUchar(0x02, 0x05);
-       KeStallExecutionProcessor(2000);
-
-       SendWait();
-       SendKey();
-       SendWake(0x00);
-
-       Port = FindNextReadPort();
-  if (Port == 0) {
-               SendWait();
-               return FALSE;
-       }
-
-       SetReadDataPort(Port);
-       KeStallExecutionProcessor(1000);
-  WriteAddress(0x01);
-       KeStallExecutionProcessor(1000);
-       return TRUE;
-}
-
-/*
- * Isolate (assign uniqued CSN) to all ISA PnP devices
- */
-static ULONG IsolatePnPCards(VOID)
-{
-       UCHAR checksum = 0x6a;
-       UCHAR chksum = 0x00;
-       UCHAR bit = 0x00;
-       ULONG data;
-       ULONG csn = 0;
-       ULONG i;
-       ULONG iteration = 1;
-
-  DPRINT("Called\n");
-
-       IsaPnPReadPort = (PUCHAR)(ISAPNP_MIN_READ_PORT - READ_DATA_PORT_STEP);
-  if (!IsolateReadDataPortSelect()) {
-    DPRINT("Could not set read data port\n");
-               return 0;
-  }
-
-       while (TRUE) {
-               for (i = 1; i <= 64; i++) {
-                       data = ReadData() << 8;
-                       KeStallExecutionProcessor(250);
-                       data = data | ReadData();
-                       KeStallExecutionProcessor(250);
-                       if (data == 0x55aa)
-                               bit = 0x01;
-                       checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1);
-                       bit = 0x00;
-               }
-               for (i = 65; i <= 72; i++) {
-                       data = ReadData() << 8;
-                       KeStallExecutionProcessor(250);
-                       data = data | ReadData();
-                       KeStallExecutionProcessor(250);
-                       if (data == 0x55aa)
-                               chksum |= (1 << (i - 65));
-               }
-               if ((checksum != 0x00) && (checksum == chksum)) {
-                       csn++;
-
-                       WriteUchar(0x06, (UCHAR) csn);
-                       KeStallExecutionProcessor(250);
-                       iteration++;
-                       SendWake(0x00);
-                       SetReadDataPort((ULONG_PTR)IsaPnPReadPort);
-                       KeStallExecutionProcessor(1000);
-                       WriteAddress(0x01);
-                       KeStallExecutionProcessor(1000);
-                       goto next;
-               }
-               if (iteration == 1) {
-      if (!IsolateReadDataPortSelect()) {
-        DPRINT("Could not set read data port\n");
-                               return 0;
-      }
-               } else if (iteration > 1) {
-                       break;
-               }
-next:
-               checksum = 0x6a;
-               chksum = 0x00;
-               bit = 0x00;
-       }
-       SendWait();
-       return csn;
-}
-
-
-static VOID Peek(PUCHAR Data, ULONG Count)
-{
-       ULONG i, j;
-       UCHAR d = 0;
-
-       for (i = 1; i <= Count; i++) {
-               for (j = 0; j < 20; j++) {
-                       d = ReadUchar(0x05);
-                       if (d & 0x1)
-                               break;
-                       KeStallExecutionProcessor(100);
-               }
-               if (!(d & 0x1)) {
-                       if (Data != NULL)
-                               *Data++ = 0xff;
-                       continue;
-               }
-               d = ReadUchar(0x04); /* PRESDI */
-               if (Data != NULL)
-                       *Data++ = d;
-       }
-}
-
-
-/*
- * Skip specified number of bytes from stream
- */
-static VOID Skip(ULONG Count)
-{
-       Peek(NULL, Count);
-}
-
-
-/*
- * Read one tag from stream
- */
-static BOOLEAN ReadTag(PUCHAR Type,
-  PUSHORT Size,
-  PBOOLEAN Small)
-{
-       UCHAR tag, tmp[2];
-
-       Peek(&tag, 1);
-  if (tag == 0) {
-    /* Invalid tag */
-    DPRINT("Invalid tag with value 0\n");
-#ifndef NDEBUG
-    for (;;);
-#endif
-               return FALSE;
-  }
-
-       if (tag & ISAPNP_RESOURCE_ITEM_TYPE) {
-    /* Large resource item */
-               *Type = (tag & 0x7f);
-               Peek(tmp, 2);
-               *Size = UCHAR2USHORT(tmp[0], tmp[1]);
-    *Small = FALSE;
-#ifndef NDEBUG
-    if (*Type > ISAPNP_LRIN_FL_MEMORY_RANGE32) {
-      DPRINT("Invalid large tag with value 0x%X\n", *Type);
-      for (;;);
-    }
-#endif
-       } else {
-    /* Small resource item */
-               *Type = (tag >> 3) & 0x0f;
-               *Size = tag & 0x07;
-    *Small = TRUE;
-#ifndef NDEBUG
-    if (*Type > ISAPNP_SRIN_END_TAG) {
-      DPRINT("Invalid small tag with value 0x%X\n", *Type);
-      for (;;);
-    }
-#endif
-  }
-#if 0
-       DPRINT("Tag = 0x%X, Type = 0x%X, Size = %d (%s)\n",
-    tag, *Type, *Size, TagName(*Type, *Small));
-#endif
-  /* Probably invalid data */
-  if ((*Type == 0xff) && (*Size == 0xffff)) {
-    DPRINT("Invalid data (Type 0x%X  Size 0x%X)\n", *Type, *Size);
-    for (;;);
-               return FALSE;
-  }
-
-       return TRUE;
-}
-
-
-/*
- * Parse ANSI name for ISA PnP logical device
- */
-static NTSTATUS ParseAnsiName(PUNICODE_STRING Name, PUSHORT Size)
-{
-  ANSI_STRING AnsiString;
-  UCHAR Buffer[256];
-  USHORT size1;
-
-  size1 = (*Size >= sizeof(Buffer)) ? (sizeof(Buffer) - 1) : *Size;
-
-  Peek(Buffer, size1);
-  Buffer[size1] = '\0';
-  *Size -= size1;
-
-  /* Clean whitespace from end of string */
-  while ((size1 > 0) && (Buffer[--size1] == ' '))
-    Buffer[size1] = '\0';
-
-  DPRINT("ANSI name: %s\n", Buffer);
-
-  RtlInitAnsiString(&AnsiString, (PCSZ)&Buffer);
-  return RtlAnsiStringToUnicodeString(Name, &AnsiString, TRUE);
-}
-
-
-/*
- * Add a resource list to the
- * resource lists of a logical device
- */
-static NTSTATUS AddResourceList(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Priority,
-  PISAPNP_CONFIGURATION_LIST *NewList)
-{
-  PISAPNP_CONFIGURATION_LIST List;
-
-  DPRINT("Adding resource list for logical device %d on card %d (Priority %d)\n",
-        LogicalDevice->Number,
-        LogicalDevice->Card->CardId,
-        Priority);
-
-  List = (PISAPNP_CONFIGURATION_LIST)
-      ExAllocatePoolWithTag(PagedPool, sizeof(ISAPNP_CONFIGURATION_LIST), TAG_ISAPNP);
-  if (!List)
-    return STATUS_INSUFFICIENT_RESOURCES;
-
-  RtlZeroMemory(List, sizeof(ISAPNP_CONFIGURATION_LIST));
-
-  List->Priority = Priority;
-
-  InitializeListHead(&List->ListHead);
-
-  InsertTailList(&LogicalDevice->Configuration, &List->ListEntry);
-
-  *NewList = List;
-
-  return STATUS_SUCCESS;
-}
-
-
-/*
- * Add a resource entry to the
- * resource list of a logical device
- */
-static NTSTATUS AddResourceDescriptor(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Priority,
-  ULONG Option,
-  PISAPNP_DESCRIPTOR *Descriptor)
-{
-  PLIST_ENTRY CurrentEntry;
-  PISAPNP_CONFIGURATION_LIST List;
-  PISAPNP_DESCRIPTOR d;
-  NTSTATUS Status;
-
-  DPRINT("Adding resource descriptor for logical device %d on card %d (%d of %d)\n",
-        LogicalDevice->Number,
-        LogicalDevice->Card->CardId,
-        LogicalDevice->CurrentDescriptorCount,
-        LogicalDevice->DescriptorCount);
-
-  d = (PISAPNP_DESCRIPTOR)
-    ExAllocatePoolWithTag(PagedPool, sizeof(ISAPNP_DESCRIPTOR), TAG_ISAPNP);
-  if (!d)
-    return STATUS_NO_MEMORY;
-
-  RtlZeroMemory(d, sizeof(ISAPNP_DESCRIPTOR));
-
-  d->Descriptor.Option = (UCHAR) Option;
-
-  *Descriptor = d;
-
-  CurrentEntry = LogicalDevice->Configuration.Flink;
-  while (CurrentEntry != &LogicalDevice->Configuration) {
-    List = CONTAINING_RECORD(
-      CurrentEntry, ISAPNP_CONFIGURATION_LIST, ListEntry);
-
-    if (List->Priority == Priority) {
-
-      LogicalDevice->ConfigurationSize += sizeof(IO_RESOURCE_DESCRIPTOR);
-      InsertTailList(&List->ListHead, &d->ListEntry);
-      LogicalDevice->CurrentDescriptorCount++;
-      if (LogicalDevice->DescriptorCount <
-        LogicalDevice->CurrentDescriptorCount) {
-        LogicalDevice->DescriptorCount =
-          LogicalDevice->CurrentDescriptorCount;
-      }
-
-      return STATUS_SUCCESS;
-    }
-    CurrentEntry = CurrentEntry->Flink;
-  }
-
-  Status = AddResourceList(LogicalDevice, Priority, &List);
-  if (NT_SUCCESS(Status)) {
-    LogicalDevice->ConfigurationSize += sizeof(IO_RESOURCE_LIST);
-    LogicalDevice->CurrentDescriptorCount = 0;
-    InsertTailList(&List->ListHead, &d->ListEntry);
-  }
-
-  return Status;
-}
-
-
-/*
- * Add IRQ resource to resources list
- */
-static NTSTATUS AddIrqResource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[3];
-  ULONG irq, i, last = 0;
-  BOOLEAN found;
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-       irq = UCHAR2USHORT(tmp[0], tmp[0]);
-
-  DPRINT("IRQ bitmask: 0x%X\n", irq);
-
-  found = FALSE;
-  for (i = 0; i < 16; i++) {
-    if (!found && (irq & (1 << i))) {
-      last = i;
-      found = TRUE;
-    }
-
-    if ((found && !(irq & (1 << i))) || (irq & (1 << i) && (i == 15))) {
-      Status = AddResourceDescriptor(LogicalDevice,
-        Priority, Option, &Descriptor);
-      if (!NT_SUCCESS(Status))
-        return Status;
-      Descriptor->Descriptor.Type = CmResourceTypeInterrupt;
-      Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-      Descriptor->Descriptor.u.Interrupt.MinimumVector = last;
-
-      if ((irq & (1 << i)) && (i == 15))
-        Descriptor->Descriptor.u.Interrupt.MaximumVector = i;
-      else
-        Descriptor->Descriptor.u.Interrupt.MaximumVector = i - 1;
-
-      DPRINT("Found IRQ range %d - %d for logical device %d on card %d\n",
-        Descriptor->Descriptor.u.Interrupt.MinimumVector,
-        Descriptor->Descriptor.u.Interrupt.MaximumVector,
-        LogicalDevice->Number,
-        LogicalDevice->Card->CardId);
-
-      found = FALSE;
-    }
-  }
-
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add DMA resource to resources list
- */
-static NTSTATUS AddDmaResource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[2];
-  ULONG dma, flags, i, last = 0;
-  BOOLEAN found;
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-       dma = tmp[0];
-  flags = tmp[1];
-
-  DPRINT("DMA bitmask: 0x%X\n", dma);
-
-  found = FALSE;
-  for (i = 0; i < 8; i++) {
-    if (!found && (dma & (1 << i))) {
-      last = i;
-      found = TRUE;
-    }
-
-    if ((found && !(dma & (1 << i))) || (dma & (1 << i) && (i == 15))) {
-      Status = AddResourceDescriptor(LogicalDevice,
-        Priority, Option, &Descriptor);
-      if (!NT_SUCCESS(Status))
-        return Status;
-      Descriptor->Descriptor.Type = CmResourceTypeDma;
-      Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-      Descriptor->Descriptor.u.Dma.MinimumChannel = last;
-
-      if ((dma & (1 << i)) && (i == 15))
-        Descriptor->Descriptor.u.Dma.MaximumChannel = i;
-      else
-        Descriptor->Descriptor.u.Dma.MaximumChannel = i - 1;
-
-      /* FIXME: Parse flags */
-
-      DPRINT("Found DMA range %d - %d for logical device %d on card %d\n",
-        Descriptor->Descriptor.u.Dma.MinimumChannel,
-        Descriptor->Descriptor.u.Dma.MaximumChannel,
-        LogicalDevice->Number,
-        LogicalDevice->Card->CardId);
-
-      found = FALSE;
-    }
-  }
-
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add port resource to resources list
- */
-static NTSTATUS AddIOPortResource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-#if 0
-  DPRINT("I/O port: size 0x%X\n", Size);
-  Skip(Size);
-#else
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[7];
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-  Status = AddResourceDescriptor(LogicalDevice,
-    Priority, Option, &Descriptor);
-  if (!NT_SUCCESS(Status))
-    return Status;
-  Descriptor->Descriptor.Type = CmResourceTypePort;
-  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-  Descriptor->Descriptor.u.Port.Length = tmp[6];
-  /* FIXME: Parse flags */
-  Descriptor->Descriptor.u.Port.Alignment = 0;
-  Descriptor->Descriptor.u.Port.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[1], tmp[2]);
-  Descriptor->Descriptor.u.Port.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[4], tmp[4]);
-
-  DPRINT("Found I/O port range 0x%X - 0x%X for logical device %d on card %d\n",
-    Descriptor->Descriptor.u.Port.MinimumAddress,
-    Descriptor->Descriptor.u.Port.MaximumAddress,
-    LogicalDevice->Number,
-    LogicalDevice->Card->CardId);
-#endif
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add fixed port resource to resources list
- */
-static NTSTATUS AddFixedIOPortResource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-#if 0
-  DPRINT("Fixed I/O port: size 0x%X\n", Size);
-  Skip(Size);
-#else
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[3];
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-  Status = AddResourceDescriptor(LogicalDevice,
-    Priority, Option, &Descriptor);
-  if (!NT_SUCCESS(Status))
-    return Status;
-  Descriptor->Descriptor.Type = CmResourceTypePort;
-  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-  Descriptor->Descriptor.u.Port.Length = tmp[2];
-  Descriptor->Descriptor.u.Port.Alignment = 0;
-  Descriptor->Descriptor.u.Port.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[0], tmp[1]);
-  Descriptor->Descriptor.u.Port.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[0], tmp[1]);
-
-  DPRINT("Found fixed I/O port range 0x%X - 0x%X for logical device %d on card %d\n",
-    Descriptor->Descriptor.u.Port.MinimumAddress,
-    Descriptor->Descriptor.u.Port.MaximumAddress,
-    LogicalDevice->Number,
-    LogicalDevice->Card->CardId);
-#endif
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add memory resource to resources list
- */
-static NTSTATUS AddMemoryResource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-#if 0
-  DPRINT("Memory range: size 0x%X\n", Size);
-  Skip(Size);
-#else
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[9];
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-  Status = AddResourceDescriptor(LogicalDevice,
-    Priority, Option, &Descriptor);
-  if (!NT_SUCCESS(Status))
-    return Status;
-  Descriptor->Descriptor.Type = CmResourceTypeMemory;
-  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-  Descriptor->Descriptor.u.Memory.Length = UCHAR2USHORT(tmp[7], tmp[8]) << 8;
-  Descriptor->Descriptor.u.Memory.Alignment = UCHAR2USHORT(tmp[5], tmp[6]);
-  Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[1], tmp[2]) << 8;
-  Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[3], tmp[4]) << 8;
-
-  DPRINT("Found memory range 0x%X - 0x%X for logical device %d on card %d\n",
-    Descriptor->Descriptor.u.Memory.MinimumAddress,
-    Descriptor->Descriptor.u.Memory.MaximumAddress,
-    LogicalDevice->Number,
-    LogicalDevice->Card->CardId);
-#endif
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add 32-bit memory resource to resources list
- */
-static NTSTATUS AddMemory32Resource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-#if 0
-  DPRINT("Memory32 range: size 0x%X\n", Size);
-  Skip(Size);
-#else
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[17];
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-  Status = AddResourceDescriptor(LogicalDevice,
-    Priority, Option, &Descriptor);
-  if (!NT_SUCCESS(Status))
-    return Status;
-  Descriptor->Descriptor.Type = CmResourceTypeMemory;
-  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-  Descriptor->Descriptor.u.Memory.Length =
-    UCHAR2ULONG(tmp[13], tmp[14], tmp[15], tmp[16]);
-  Descriptor->Descriptor.u.Memory.Alignment =
-    UCHAR2ULONG(tmp[9], tmp[10], tmp[11], tmp[12]);
-  Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart =
-    UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]);
-  Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart =
-    UCHAR2ULONG(tmp[5], tmp[6], tmp[7], tmp[8]);
-
-  DPRINT("Found memory32 range 0x%X - 0x%X for logical device %d on card %d\n",
-    Descriptor->Descriptor.u.Memory.MinimumAddress,
-    Descriptor->Descriptor.u.Memory.MaximumAddress,
-    LogicalDevice->Number,
-    LogicalDevice->Card->CardId);
-#endif
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add 32-bit fixed memory resource to resources list
- */
-static NTSTATUS AddFixedMemory32Resource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-#if 0
-  DPRINT("Memory32 range: size 0x%X\n", Size);
-  Skip(Size);
-#else
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[17];
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-  Status = AddResourceDescriptor(LogicalDevice,
-    Priority, Option, &Descriptor);
-  if (!NT_SUCCESS(Status))
-    return Status;
-  Descriptor->Descriptor.Type = CmResourceTypeMemory;
-  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-  Descriptor->Descriptor.u.Memory.Length =
-    UCHAR2ULONG(tmp[9], tmp[10], tmp[11], tmp[12]);
-  Descriptor->Descriptor.u.Memory.Alignment =
-    UCHAR2ULONG(tmp[5], tmp[6], tmp[7], tmp[8]);
-  Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart =
-    UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]);
-  Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart =
-    UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]);
-
-  DPRINT("Found fixed memory32 range 0x%X - 0x%X for logical device %d on card %d\n",
-    Descriptor->Descriptor.u.Memory.MinimumAddress,
-    Descriptor->Descriptor.u.Memory.MaximumAddress,
-    LogicalDevice->Number,
-    LogicalDevice->Card->CardId);
-#endif
-  return STATUS_SUCCESS;
-}
-
-
-/*
- * Parse logical device tag
- */
-static PISAPNP_LOGICAL_DEVICE ParseLogicalDevice(
-  PISAPNP_DEVICE_EXTENSION DeviceExtension,
-  PISAPNP_CARD Card,
-  ULONG Size,
-  USHORT Number)
-{
-       UCHAR tmp[6];
-       PISAPNP_LOGICAL_DEVICE LogicalDevice;
-
-  DPRINT("Card %d  Number %d\n", Card->CardId, Number);
-
-  Peek(tmp, Size);
-
-  LogicalDevice = (PISAPNP_LOGICAL_DEVICE)ExAllocatePoolWithTag(
-    PagedPool, sizeof(ISAPNP_LOGICAL_DEVICE), TAG_ISAPNP);
-       if (!LogicalDevice)
-               return NULL;
-
-  RtlZeroMemory(LogicalDevice, sizeof(ISAPNP_LOGICAL_DEVICE));
-
-  LogicalDevice->Number = Number;
-       LogicalDevice->VendorId = UCHAR2USHORT(tmp[0], tmp[1]);
-       LogicalDevice->DeviceId = UCHAR2USHORT(tmp[2], tmp[3]);
-       LogicalDevice->Regs = tmp[4];
-       LogicalDevice->Card = Card;
-       if (Size > 5)
-               LogicalDevice->Regs |= tmp[5] << 8;
-
-  InitializeListHead(&LogicalDevice->Configuration);
-
-  ExInterlockedInsertTailList(&Card->LogicalDevices,
-    &LogicalDevice->CardListEntry,
-    &Card->LogicalDevicesLock);
-
-  ExInterlockedInsertTailList(&DeviceExtension->DeviceListHead,
-    &LogicalDevice->DeviceListEntry,
-    &DeviceExtension->GlobalListLock);
-
-  DeviceExtension->DeviceListCount++;
-
-       return LogicalDevice;
-}
-
-
-/*
- * Parse resource map for logical device
- */
-static BOOLEAN CreateLogicalDevice(PISAPNP_DEVICE_EXTENSION DeviceExtension,
-  PISAPNP_CARD Card, USHORT Size)
-{
-       ULONG number = 0, skip = 0, compat = 0;
-       UCHAR type, tmp[17];
-  PISAPNP_LOGICAL_DEVICE LogicalDevice;
-  BOOLEAN Small;
-  ULONG Priority = 0;
-  ULONG Option = IO_RESOURCE_REQUIRED;
-
-  DPRINT("Card %d  Size %d\n", Card->CardId, Size);
-
-  LogicalDevice = ParseLogicalDevice(DeviceExtension, Card, Size, (USHORT) number++);
-       if (!LogicalDevice)
-               return FALSE;
-
-  while (TRUE) {
-               if (!ReadTag(&type, &Size, &Small))
-                       return FALSE;
-
-                if (skip && !(Small && ((type == ISAPNP_SRIN_LDEVICE_ID)
-      || (type == ISAPNP_SRIN_END_TAG))))
-                       goto skip;
-
-    if (Small) {
-               switch (type) {
-               case ISAPNP_SRIN_LDEVICE_ID:
-        if ((Size >= 5) && (Size <= 6)) {
-          LogicalDevice = ParseLogicalDevice(
-            DeviceExtension, Card, Size, (USHORT)number++);
-               if (!LogicalDevice)
-               return FALSE;
-                               Size = 0;
-                               skip = 0;
-                       } else {
-                               skip = 1;
-                         }
-        Priority = 0;
-        Option = IO_RESOURCE_REQUIRED;
-                         compat = 0;
-                         break;
-
-                 case ISAPNP_SRIN_CDEVICE_ID:
-                         if ((Size == 4) && (compat < MAX_COMPATIBLE_ID)) {
-                                 Peek(tmp, 4);
-                                 LogicalDevice->CVendorId[compat] = UCHAR2USHORT(tmp[0], tmp[1]);
-                                 LogicalDevice->CDeviceId[compat] = UCHAR2USHORT(tmp[2], tmp[3]);
-                                 compat++;
-                                 Size = 0;
-                         }
-                         break;
-
-                 case ISAPNP_SRIN_IRQ_FORMAT:
-                       if ((Size < 2) || (Size > 3))
-                                 goto skip;
-                         AddIrqResource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_SRIN_DMA_FORMAT:
-                       if (Size != 2)
-                                 goto skip;
-        AddDmaResource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_SRIN_START_DFUNCTION:
-                       if (Size > 1)
-                                 goto skip;
-
-        if (Size > 0) {
-                               Peek(tmp, Size);
-          Priority = tmp[0];
-                                 Size = 0;
-          /* FIXME: Maybe use IO_RESOURCE_PREFERRED for some */
-          Option = IO_RESOURCE_ALTERNATIVE;
-        } else {
-          Priority = 0;
-          Option = IO_RESOURCE_ALTERNATIVE;
-        }
-
-        DPRINT("   Start priority %d   \n", Priority);
-
-        LogicalDevice->CurrentDescriptorCount = 0;
-
-                         break;
-
-               case ISAPNP_SRIN_END_DFUNCTION:
-
-        DPRINT("   End priority %d   \n", Priority);
-
-                       if (Size != 0)
-                               goto skip;
-        Priority = 0;
-        Option = IO_RESOURCE_REQUIRED;
-        LogicalDevice->CurrentDescriptorCount = 0;
-                         break;
-
-               case ISAPNP_SRIN_IO_DESCRIPTOR:
-                       if (Size != 7)
-                               goto skip;
-                         AddIOPortResource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_SRIN_FL_IO_DESCRIPOTOR:
-                         if (Size != 3)
-                               goto skip;
-                         AddFixedIOPortResource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_SRIN_VENDOR_DEFINED:
-                       break;
-
-                 case ISAPNP_SRIN_END_TAG:
-                         if (Size > 0)
-                               Skip(Size);
-        return FALSE;
-
-                 default:
-                       DPRINT("Ignoring small tag of type 0x%X for logical device %d on card %d\n",
-          type, LogicalDevice->Number, Card->CardId);
-      }
-    } else {
-      switch (type) {
-                 case ISAPNP_LRIN_MEMORY_RANGE:
-                         if (Size != 9)
-                               goto skip;
-                         AddMemoryResource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_LRIN_ID_STRING_ANSI:
-        ParseAnsiName(&LogicalDevice->Name, &Size);
-                         break;
-
-                 case ISAPNP_LRIN_ID_STRING_UNICODE:
-                       break;
-
-               case ISAPNP_LRIN_VENDOR_DEFINED:
-                         break;
-
-                 case ISAPNP_LRIN_MEMORY_RANGE32:
-                       if (Size != 17)
-                                 goto skip;
-                         AddMemory32Resource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_LRIN_FL_MEMORY_RANGE32:
-                       if (Size != 17)
-                                 goto skip;
-                         AddFixedMemory32Resource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 default:
-                       DPRINT("Ignoring large tag of type 0x%X for logical device %d on card %d\n",
-          type, LogicalDevice->Number, Card->CardId);
-                 }
-    }
-skip:
-  if (Size > 0)
-         Skip(Size);
-       }
-
-       return TRUE;
-}
-
-
-/*
- * Parse resource map for ISA PnP card
- */
-static BOOLEAN ParseResourceMap(PISAPNP_DEVICE_EXTENSION DeviceExtension,
-  PISAPNP_CARD Card)
-{
-       UCHAR type, tmp[17];
-       USHORT size;
-  BOOLEAN Small;
-
-  DPRINT("Card %d\n", Card->CardId);
-
-       while (TRUE) {
-               if (!ReadTag(&type, &size, &Small))
-                       return FALSE;
-
-    if (Small) {
-                 switch (type) {
-                 case ISAPNP_SRIN_VERSION:
-                       if (size != 2)
-                               goto skip;
-                       Peek(tmp, 2);
-                         Card->PNPVersion = tmp[0];
-                         Card->ProductVersion = tmp[1];
-                         size = 0;
-                         break;
-
-      case ISAPNP_SRIN_LDEVICE_ID:
-                       if ((size >= 5) && (size <= 6)) {
-                                 if (!CreateLogicalDevice(DeviceExtension, Card, size))
-                                       return FALSE;
-                                 size = 0;
-                         }
-                         break;
-
-      case ISAPNP_SRIN_CDEVICE_ID:
-        /* FIXME: Parse compatible IDs */
-        break;
-
-                 case ISAPNP_SRIN_END_TAG:
-                         if (size > 0)
-                               Skip(size);
-                         return TRUE;
-
-                 default:
-                       DPRINT("Ignoring small tag Type 0x%X for Card %d\n", type, Card->CardId);
-                 }
-    } else {
-                 switch (type) {
-                 case ISAPNP_LRIN_ID_STRING_ANSI:
-                       ParseAnsiName(&Card->Name, &size);
-                         break;
-
-      default:
-                       DPRINT("Ignoring large tag Type 0x%X for Card %d\n",
-          type, Card->CardId);
-                 }
-    }
-skip:
-  if (size > 0)
-    Skip(size);
-  }
-
-  return TRUE;
-}
-
-
-/*
- * Compute ISA PnP checksum for first eight bytes
- */
-static UCHAR Checksum(PUCHAR data)
-{
-       ULONG i, j;
-       UCHAR checksum = 0x6a, bit, b;
-
-       for (i = 0; i < 8; i++) {
-               b = data[i];
-               for (j = 0; j < 8; j++) {
-                       bit = 0;
-                       if (b & (1 << j))
-                               bit = 1;
-                       checksum = ((((checksum ^ (checksum >> 1)) &
-        0x01) ^ bit) << 7) | (checksum >> 1);
-               }
-       }
-       return checksum;
-}
-
-
-/*
- * Build a resource list for a logical ISA PnP device
- */
-static NTSTATUS BuildResourceList(PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  PIO_RESOURCE_LIST DestinationList,
-  ULONG Priority)
-{
-  PLIST_ENTRY CurrentEntry, Entry;
-  PISAPNP_CONFIGURATION_LIST List;
-  PISAPNP_DESCRIPTOR Descriptor;
-  ULONG i;
-
-  if (IsListEmpty(&LogicalDevice->Configuration))
-    return STATUS_NOT_FOUND;
-
-  CurrentEntry = LogicalDevice->Configuration.Flink;
-  while (CurrentEntry != &LogicalDevice->Configuration) {
-    List = CONTAINING_RECORD(
-      CurrentEntry, ISAPNP_CONFIGURATION_LIST, ListEntry);
-
-    if (List->Priority == Priority) {
-
-      DPRINT("Logical device %d  DestinationList %p\n",
-        LogicalDevice->Number,
-        DestinationList);
-
-      DestinationList->Version = 1;
-      DestinationList->Revision = 1;
-      DestinationList->Count = LogicalDevice->DescriptorCount;
-
-      i = 0;
-      Entry = List->ListHead.Flink;
-      while (Entry != &List->ListHead) {
-        Descriptor = CONTAINING_RECORD(
-          Entry, ISAPNP_DESCRIPTOR, ListEntry);
-
-        DPRINT("Logical device %d  Destination %p(%d)\n",
-          LogicalDevice->Number,
-          &DestinationList->Descriptors[i],
-          i);
-
-        RtlCopyMemory(&DestinationList->Descriptors[i],
-          &Descriptor->Descriptor,
-          sizeof(IO_RESOURCE_DESCRIPTOR));
-
-        i++;
-
-        Entry = Entry->Flink;
-      }
-
-      RemoveEntryList(&List->ListEntry);
-
-      ExFreePool(List);
-
-      return STATUS_SUCCESS;
-    }
-
-    CurrentEntry = CurrentEntry->Flink;
-  }
-
-  return STATUS_UNSUCCESSFUL;
-}
-
-
-/*
- * Build resource lists for a logical ISA PnP device
- */
-static NTSTATUS BuildResourceLists(PISAPNP_LOGICAL_DEVICE LogicalDevice)
-{
-  ULONG ListSize;
-  ULONG Priority;
-  ULONG SingleListSize;
-  PIO_RESOURCE_LIST p;
-  NTSTATUS Status;
-
-  ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST)
-    - sizeof(IO_RESOURCE_LIST)
-    + LogicalDevice->ConfigurationSize;
-
-  DPRINT("Logical device %d  ListSize 0x%X  ConfigurationSize 0x%X  DescriptorCount %d\n",
-    LogicalDevice->Number, ListSize,
-    LogicalDevice->ConfigurationSize,
-    LogicalDevice->DescriptorCount);
-
-  LogicalDevice->ResourceLists =
-    (PIO_RESOURCE_REQUIREMENTS_LIST)ExAllocatePoolWithTag(
-      PagedPool, ListSize, TAG_ISAPNP);
-       if (!LogicalDevice->ResourceLists)
-               return STATUS_INSUFFICIENT_RESOURCES;
-
-  RtlZeroMemory(LogicalDevice->ResourceLists, ListSize);
-
-  SingleListSize = sizeof(IO_RESOURCE_LIST) +
-    (LogicalDevice->DescriptorCount - 1) *
-    sizeof(IO_RESOURCE_DESCRIPTOR);
-
-  DPRINT("SingleListSize %d\n", SingleListSize);
-
-  Priority = 0;
-  p = &LogicalDevice->ResourceLists->List[0];
-  do {
-    Status = BuildResourceList(LogicalDevice, p, Priority);
-    if (NT_SUCCESS(Status)) {
-      p = (PIO_RESOURCE_LIST)((ULONG_PTR)p + SingleListSize);
-      Priority++;
-    }
-  } while (Status != STATUS_NOT_FOUND);
-
-  LogicalDevice->ResourceLists->ListSize = ListSize;
-  LogicalDevice->ResourceLists->AlternativeLists = Priority + 1;
-
-  return STATUS_SUCCESS;
-}
-
-
-/*
- * Build resource lists for a ISA PnP card
- */
-static NTSTATUS BuildResourceListsForCard(PISAPNP_CARD Card)
-{
-  PISAPNP_LOGICAL_DEVICE LogicalDevice;
-  PLIST_ENTRY CurrentEntry;
-  NTSTATUS Status;
-
-  CurrentEntry = Card->LogicalDevices.Flink;
-  while (CurrentEntry != &Card->LogicalDevices) {
-    LogicalDevice = CONTAINING_RECORD(
-      CurrentEntry, ISAPNP_LOGICAL_DEVICE, CardListEntry);
-    Status = BuildResourceLists(LogicalDevice);
-    if (!NT_SUCCESS(Status))
-      return Status;
-    CurrentEntry = CurrentEntry->Flink;
-  }
-
-  return STATUS_SUCCESS;
-}
-
-
-/*
- * Build resource lists for all present ISA PnP cards
- */
-static NTSTATUS BuildResourceListsForAll(
-  PISAPNP_DEVICE_EXTENSION DeviceExtension)
-{
-  PLIST_ENTRY CurrentEntry;
-  PISAPNP_CARD Card;
-  NTSTATUS Status;
-
-  CurrentEntry = DeviceExtension->CardListHead.Flink;
-  while (CurrentEntry != &DeviceExtension->CardListHead) {
-    Card = CONTAINING_RECORD(
-      CurrentEntry, ISAPNP_CARD, ListEntry);
-    Status = BuildResourceListsForCard(Card);
-    if (!NT_SUCCESS(Status))
-      return Status;
-    CurrentEntry = CurrentEntry->Flink;
-  }
-
-  return STATUS_SUCCESS;
-}
-
-
 /*
- * Build device list for all present ISA PnP cards
+ * PROJECT:         ReactOS ISA PnP Bus driver
+ * FILE:            isapnp.c
+ * PURPOSE:         Driver entry
+ * PROGRAMMERS:     Cameron Gutman (cameron.gutman@reactos.org)
  */
-static NTSTATUS BuildDeviceList(PISAPNP_DEVICE_EXTENSION DeviceExtension)
-{
-       ULONG csn;
-       UCHAR header[9], checksum;
-  PISAPNP_CARD Card;
-
-  DPRINT("Called\n");
-
-       SendWait();
-       SendKey();
-       for (csn = 1; csn <= 10; csn++) {
-               SendWake((UCHAR)csn);
-               Peek(header, 9);
-               checksum = Checksum(header);
-
-    if (checksum == 0x00 || checksum != header[8])  /* Invalid CSN */
-                       continue;
-
-               DPRINT("VENDOR: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-                       header[0], header[1], header[2], header[3],
-                       header[4], header[5], header[6], header[7], header[8]);
-
-    Card = (PISAPNP_CARD)ExAllocatePoolWithTag(
-      PagedPool, sizeof(ISAPNP_CARD), TAG_ISAPNP);
-    if (!Card)
-      return STATUS_INSUFFICIENT_RESOURCES;
-
-    RtlZeroMemory(Card, sizeof(ISAPNP_CARD));
-
-               Card->CardId = (USHORT) csn;
-               Card->VendorId = (header[1] << 8) | header[0];
-               Card->DeviceId = (header[3] << 8) | header[2];
-               Card->Serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4];
-
-    InitializeListHead(&Card->LogicalDevices);
-    KeInitializeSpinLock(&Card->LogicalDevicesLock);
-
-    ParseResourceMap(DeviceExtension, Card);
-
-    ExInterlockedInsertTailList(&DeviceExtension->CardListHead,
-      &Card->ListEntry,
-      &DeviceExtension->GlobalListLock);
-       }
-
-  return STATUS_SUCCESS;
-}
+#include <isapnp.h>
 
+#define NDEBUG
+#include <debug.h>
 
-static NTSTATUS
-ISAPNPQueryBusRelations(
-  IN PDEVICE_OBJECT DeviceObject,
-  IN PIRP Irp,
-  PIO_STACK_LOCATION IrpSp)
+static
+NTSTATUS
+NTAPI
+ForwardIrpCompletion(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp,
+       IN PVOID Context)
 {
-  PISAPNP_DEVICE_EXTENSION DeviceExtension;
-  PISAPNP_LOGICAL_DEVICE LogicalDevice;
-  PDEVICE_RELATIONS Relations;
-  PLIST_ENTRY CurrentEntry;
-  NTSTATUS Status = STATUS_SUCCESS;
-  ULONG Size;
-  ULONG i;
-
-  DPRINT("Called\n");
-
-  DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-  if (Irp->IoStatus.Information) {
-    /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
-              structure so we must merge this structure with our own */
-  }
-
-  Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
-    (DeviceExtension->DeviceListCount - 1);
-  Relations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(PagedPool, Size, TAG_ISAPNP);
-  if (!Relations)
-    return STATUS_INSUFFICIENT_RESOURCES;
-
-  Relations->Count = DeviceExtension->DeviceListCount;
-
-  i = 0;
-  CurrentEntry = DeviceExtension->DeviceListHead.Flink;
-  while (CurrentEntry != &DeviceExtension->DeviceListHead) {
-    LogicalDevice = CONTAINING_RECORD(
-      CurrentEntry, ISAPNP_LOGICAL_DEVICE, DeviceListEntry);
-
-    if (!LogicalDevice->Pdo) {
-      /* Create a physical device object for the
-         device as it does not already have one */
-      Status = IoCreateDevice(DeviceObject->DriverObject, 0,
-        NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &LogicalDevice->Pdo);
-      if (!NT_SUCCESS(Status)) {
-        DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
-        ExFreePool(Relations);
-        return Status;
-      }
-
-      LogicalDevice->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
-    }
-
-    /* Reference the physical device object. The PnP manager
-       will dereference it again when it is no longer needed */
-    ObReferenceObject(LogicalDevice->Pdo);
-
-    Relations->Objects[i] = LogicalDevice->Pdo;
+  if (Irp->PendingReturned)
+    KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
 
-    i++;
-
-    CurrentEntry = CurrentEntry->Flink;
-  }
-
-  Irp->IoStatus.Information = (ULONG_PTR)Relations;
-
-  return Status;
+  return STATUS_MORE_PROCESSING_REQUIRED;
 }
 
-
-static NTSTATUS
-ISAPNPQueryDeviceRelations(
-  IN PDEVICE_OBJECT DeviceObject,
-  IN PIRP Irp,
-  PIO_STACK_LOCATION IrpSp)
+NTSTATUS
+NTAPI
+IsaForwardIrpSynchronous(
+       IN PISAPNP_FDO_EXTENSION FdoExt,
+       IN PIRP Irp)
 {
-  PISAPNP_DEVICE_EXTENSION DeviceExtension;
+  KEVENT Event;
   NTSTATUS Status;
 
-  DPRINT("Called\n");
-
-  DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+  KeInitializeEvent(&Event, NotificationEvent, FALSE);
+  IoCopyCurrentIrpStackLocationToNext(Irp);
 
-  if (DeviceExtension->State == dsStopped)
-    return STATUS_UNSUCCESSFUL;
+  IoSetCompletionRoutine(Irp, ForwardIrpCompletion, &Event, TRUE, TRUE, TRUE);
 
-  switch (IrpSp->Parameters.QueryDeviceRelations.Type) {
-    case BusRelations:
-      Status = ISAPNPQueryBusRelations(DeviceObject, Irp, IrpSp);
-      break;
-
-    default:
-      Status = STATUS_NOT_IMPLEMENTED;
+  Status = IoCallDriver(FdoExt->Ldo, Irp);
+  if (Status == STATUS_PENDING)
+  {
+      Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+      if (NT_SUCCESS(Status))
+         Status = Irp->IoStatus.Status;
   }
 
   return Status;
 }
 
 
-static NTSTATUS
-ISAPNPStartDevice(
-  IN PDEVICE_OBJECT DeviceObject,
-  IN PIRP Irp,
-  PIO_STACK_LOCATION IrpSp)
-{
-  PISAPNP_DEVICE_EXTENSION DeviceExtension;
-  NTSTATUS Status;
-  ULONG NumCards;
-
-  DPRINT("Called\n");
-
-  DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-  if (DeviceExtension->State == dsStarted)
-    return STATUS_SUCCESS;
-
-  NumCards = IsolatePnPCards();
-
-  DPRINT("Number of ISA PnP cards found: %d\n", NumCards);
-
-  Status = BuildDeviceList(DeviceExtension);
-  if (!NT_SUCCESS(Status)) {
-    DPRINT("BuildDeviceList() failed with status 0x%X\n", Status);
-    return Status;
-  }
-
-  Status = BuildResourceListsForAll(DeviceExtension);
-  if (!NT_SUCCESS(Status)) {
-    DPRINT("BuildResourceListsForAll() failed with status 0x%X\n", Status);
-    return Status;
-  }
-
-  DeviceExtension->State = dsStarted;
-
-  return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS
-ISAPNPStopDevice(
-  IN PDEVICE_OBJECT DeviceObject,
-  IN PIRP Irp,
-  PIO_STACK_LOCATION IrpSp)
-{
-  PISAPNP_DEVICE_EXTENSION DeviceExtension;
-
-  DPRINT("Called\n");
-
-  DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-  if (DeviceExtension->State != dsStopped) {
-    /* FIXME: Stop device */
-    DeviceExtension->State = dsStopped;
-  }
-
-  return STATUS_SUCCESS;
-}
-
-
-static DRIVER_DISPATCH ISAPNPDispatchOpenClose;
-static NTSTATUS
+static
+NTSTATUS
 NTAPI
-ISAPNPDispatchOpenClose(
+IsaCreateClose(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
 {
-  DPRINT("Called\n");
-
   Irp->IoStatus.Status = STATUS_SUCCESS;
   Irp->IoStatus.Information = FILE_OPENED;
-  IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-  return STATUS_SUCCESS;
-}
 
-static DRIVER_DISPATCH ISAPNPDispatchReadWrite;
-static NTSTATUS
-NTAPI
-ISAPNPDispatchReadWrite(
-  IN PDEVICE_OBJECT PhysicalDeviceObject,
-  IN PIRP Irp)
-{
-  DPRINT("Called\n");
+  DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
 
-  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-  Irp->IoStatus.Information = 0;
   IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-  return STATUS_UNSUCCESSFUL;
+  return STATUS_SUCCESS;
 }
 
-static DRIVER_DISPATCH ISAPNPDispatchDeviceControl;
-static NTSTATUS
+static
+NTSTATUS
 NTAPI
-ISAPNPDispatchDeviceControl(
+IsaIoctl(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
 {
-  PIO_STACK_LOCATION IrpSp;
+  PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
   NTSTATUS Status;
 
-  DPRINT("Called\n");
-
-  Irp->IoStatus.Information = 0;
-
-  IrpSp = IoGetCurrentIrpStackLocation(Irp);
-  switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
-  default:
-    DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
-    Status = STATUS_NOT_IMPLEMENTED;
-    break;
-  }
+  DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
 
-  if (Status != STATUS_PENDING) {
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+  switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
+  {
+     default:
+        DPRINT1("Unknown ioctl code: %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
+        Status = STATUS_NOT_SUPPORTED;
+        break;
   }
 
-  DPRINT("Leaving. Status 0x%X\n", Status);
+  Irp->IoStatus.Status = Status;
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
   return Status;
 }
 
-static DRIVER_DISPATCH ISAPNPControl;
-static NTSTATUS
+static
+NTSTATUS
 NTAPI
-ISAPNPControl(
+IsaReadWrite(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
 {
-  PIO_STACK_LOCATION IrpSp;
-  NTSTATUS Status;
-
-  DPRINT("Called\n");
-
-  IrpSp = IoGetCurrentIrpStackLocation(Irp);
-  switch (IrpSp->MinorFunction) {
-  case IRP_MN_QUERY_DEVICE_RELATIONS:
-    Status = ISAPNPQueryDeviceRelations(DeviceObject, Irp, IrpSp);
-    break;
-
-  case IRP_MN_START_DEVICE:
-    Status = ISAPNPStartDevice(DeviceObject, Irp, IrpSp);
-    break;
-
-  case IRP_MN_STOP_DEVICE:
-    Status = ISAPNPStopDevice(DeviceObject, Irp, IrpSp);
-    break;
+  DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
 
-  case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
-    /* Nothing to do here */
-    DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
-    Status = Irp->IoStatus.Status;
-    break;
-
-  default:
-    DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
-    Status = STATUS_NOT_IMPLEMENTED;
-    break;
-  }
-
-  if (Status != STATUS_PENDING) {
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-  }
+  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+  Irp->IoStatus.Information = 0;
 
-  DPRINT("Leaving. Status 0x%X\n", Status);
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-  return Status;
+  return STATUS_NOT_SUPPORTED;
 }
 
-
-static NTSTATUS
+static
+NTSTATUS
 NTAPI
-ISAPNPAddDevice(
+IsaAddDevice(
   IN PDRIVER_OBJECT DriverObject,
   IN PDEVICE_OBJECT PhysicalDeviceObject)
 {
-  PISAPNP_DEVICE_EXTENSION DeviceExtension;
   PDEVICE_OBJECT Fdo;
+  PISAPNP_FDO_EXTENSION FdoExt;
   NTSTATUS Status;
 
-  DPRINT("Called\n");
+  DPRINT("%s(%p, %p)\n", __FUNCTION__, DriverObject, PhysicalDeviceObject);
 
-  Status = IoCreateDevice(DriverObject, sizeof(ISAPNP_DEVICE_EXTENSION),
-    NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo);
-  if (!NT_SUCCESS(Status)) {
-    DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
-    return Status;
+  Status = IoCreateDevice(DriverObject,
+                          sizeof(*FdoExt),
+                          NULL,
+                          FILE_DEVICE_BUS_EXTENDER,
+                          FILE_DEVICE_SECURE_OPEN,
+                          TRUE,
+                          &Fdo);
+  if (!NT_SUCCESS(Status))
+  {
+      DPRINT1("Failed to create FDO (0x%x)\n", Status);
+      return Status;
   }
 
-  DeviceExtension = (PISAPNP_DEVICE_EXTENSION)Fdo->DeviceExtension;
-
-  DeviceExtension->Pdo = PhysicalDeviceObject;
+  FdoExt = Fdo->DeviceExtension;
+  RtlZeroMemory(FdoExt, sizeof(*FdoExt));
 
-  DeviceExtension->Ldo =
-    IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject);
+  FdoExt->Common.Self = Fdo;
+  FdoExt->Common.IsFdo = TRUE;
+  FdoExt->Common.State = dsStopped;
+  FdoExt->Pdo = PhysicalDeviceObject;
+  FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo,
+                                            PhysicalDeviceObject);
 
-  InitializeListHead(&DeviceExtension->CardListHead);
-  InitializeListHead(&DeviceExtension->DeviceListHead);
-  DeviceExtension->DeviceListCount = 0;
-  KeInitializeSpinLock(&DeviceExtension->GlobalListLock);
-
-  DeviceExtension->State = dsStopped;
+  InitializeListHead(&FdoExt->DeviceListHead);
+  KeInitializeSpinLock(&FdoExt->Lock);
 
   Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
-  DPRINT("Done AddDevice\n");
-
   return STATUS_SUCCESS;
 }
 
+static
+NTSTATUS
+NTAPI
+IsaPnp(
+  IN PDEVICE_OBJECT DeviceObject,
+  IN PIRP Irp)
+{
+  PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+  PISAPNP_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension;
+
+  DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
+
+  if (DevExt->IsFdo)
+  {
+     return IsaFdoPnp((PISAPNP_FDO_EXTENSION)DevExt,
+                      Irp,
+                      IrpSp);
+  }
+  else
+  {
+     return IsaPdoPnp((PISAPNP_LOGICAL_DEVICE)DevExt,
+                      Irp,
+                      IrpSp);
+  }
+}
 
 NTSTATUS
 NTAPI
@@ -1731,15 +185,15 @@ DriverEntry(
   IN PDRIVER_OBJECT DriverObject,
   IN PUNICODE_STRING RegistryPath)
 {
-  DbgPrint("ISA Plug and Play Bus Driver\n");
+  DPRINT("%s(%p, %wZ)\n", __FUNCTION__, DriverObject, RegistryPath);
 
-  DriverObject->MajorFunction[IRP_MJ_CREATE] = ISAPNPDispatchOpenClose;
-  DriverObject->MajorFunction[IRP_MJ_CLOSE] = ISAPNPDispatchOpenClose;
-  DriverObject->MajorFunction[IRP_MJ_READ] = ISAPNPDispatchReadWrite;
-  DriverObject->MajorFunction[IRP_MJ_WRITE] = ISAPNPDispatchReadWrite;
-  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ISAPNPDispatchDeviceControl;
-  DriverObject->MajorFunction[IRP_MJ_PNP] = ISAPNPControl;
-  DriverObject->DriverExtension->AddDevice = ISAPNPAddDevice;
+  DriverObject->MajorFunction[IRP_MJ_CREATE] = IsaCreateClose;
+  DriverObject->MajorFunction[IRP_MJ_CLOSE] = IsaCreateClose;
+  DriverObject->MajorFunction[IRP_MJ_READ] = IsaReadWrite;
+  DriverObject->MajorFunction[IRP_MJ_WRITE] = IsaReadWrite;
+  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsaIoctl;
+  DriverObject->MajorFunction[IRP_MJ_PNP] = IsaPnp;
+  DriverObject->DriverExtension->AddDevice = IsaAddDevice;
 
   return STATUS_SUCCESS;
 }
index 59697b9..85fcb78 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <ntddk.h>
+#include <wdm.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -8,330 +8,87 @@ extern "C" {
 
 #define TAG_ISAPNP 'PNPI'
 
-#define IO_RESOURCE_REQUIRED  0x00  //ROS Extension
-
-#define ISAPNP_ADDRESS_PORT   0x0279    // ADDRESS (W)
-#define ISAPNP_WRITE_PORT     0x0A79    // WRITE_DATA (W)
-#define ISAPNP_MIN_READ_PORT  0x0203    // READ_DATA (R)
-#define ISAPNP_MAX_READ_PORT  0x03FF    // READ_DATA (R)
-
-// Card control registers
-#define ISAPNP_CARD_READ_DATA_PORT   0x00  // Set READ_DATA port
-#define ISAPNP_CARD_ISOLATION        0x01  // Isolation
-#define ISAPNP_CARD_CONFIG_COTROL    0x02  // Configuration control
-#define ISAPNP_CARD_WAKECSN          0x03  // Wake[CSN]
-#define ISAPNP_CARD_RESOUCE_DATA     0x04  // Resource data port
-#define ISAPNP_CARD_STATUS           0x05  // Status port
-#define ISAPNP_CARD_CSN              0x06  // Card Select Number port
-#define ISAPNP_CARD_LOG_DEVICE_NUM   0x07  // Logical Device Number
-#define ISAPNP_CARD_RESERVED         0x08  // Card level reserved
-#define ISAPNP_CARD_VENDOR_DEFINED   0x20  // Vendor defined
-
-// Logical device control registers
-#define ISAPNP_CONTROL_ACTIVATE         0x30  // Activate logical device
-#define ISAPNP_CONTROL_IO_RANGE_CHECK   0x31  // I/O range conflict check
-#define ISAPNP_CONTROL_LDC_RESERVED     0x32  // Logical Device Control reserved
-#define ISAPNP_CONTROL_LDCV_RESERVED    0x38  // Logical Device Control Vendor reserved
-
-// Logical device configuration registers
-#define ISAPNP_CONFIG_MEMORY_BASE2    0x00  // Memory base address bits 23-16
-#define ISAPNP_CONFIG_MEMORY_BASE1    0x01  // Memory base address bits 15-8
-#define ISAPNP_CONFIG_MEMORY_CONTROL  0x02  // Memory control
-#define ISAPNP_CONFIG_MEMORY_LIMIT2   0x03  // Memory limit bits 23-16
-#define ISAPNP_CONFIG_MEMORY_LIMIT1   0x04  // Memory limit bits 15-8
-
-#define ISAPNP_CONFIG_MEMORY_DESC0    0x40  // Memory descriptor 0
-#define ISAPNP_CONFIG_MEMORY_DESC1    0x48  // Memory descriptor 1
-#define ISAPNP_CONFIG_MEMORY_DESC2    0x50  // Memory descriptor 2
-#define ISAPNP_CONFIG_MEMORY_DESC3    0x58  // Memory descriptor 3
-
-#define ISAPNP_CONFIG_MEMORY32_BASE3    0x00  // 32-bit memory base address bits 31-24
-#define ISAPNP_CONFIG_MEMORY32_BASE2    0x01  // 32-bit memory base address bits 23-16
-#define ISAPNP_CONFIG_MEMORY32_BASE1    0x01  // 32-bit memory base address bits 15-8
-#define ISAPNP_CONFIG_MEMORY32_CONTROL  0x02  // 32-bit memory control
-#define ISAPNP_CONFIG_MEMORY32_LIMIT3   0x03  // 32-bit memory limit bits 31-24
-#define ISAPNP_CONFIG_MEMORY32_LIMIT2   0x04  // 32-bit memory limit bits 23-16
-#define ISAPNP_CONFIG_MEMORY32_LIMIT1   0x05  // 32-bit memory limit bits 15-8
-
-#define ISAPNP_CONFIG_MEMORY32_DESC0  0x76  // 32-bit memory descriptor 0
-#define ISAPNP_CONFIG_MEMORY32_DESC1  0x80  // 32-bit memory descriptor 1
-#define ISAPNP_CONFIG_MEMORY32_DESC2  0x90  // 32-bit memory descriptor 2
-#define ISAPNP_CONFIG_MEMORY32_DESC3  0xA0  // 32-bit memory descriptor 3
-
-#define ISAPNP_CONFIG_IO_BASE1        0x00  // I/O port base address bits 15-8
-#define ISAPNP_CONFIG_IO_BASE0        0x01  // I/O port base address bits 7-0
-
-#define ISAPNP_CONFIG_IO_DESC0    0x60  // I/O port descriptor 0
-#define ISAPNP_CONFIG_IO_DESC1    0x62  // I/O port descriptor 1
-#define ISAPNP_CONFIG_IO_DESC2    0x64  // I/O port descriptor 2
-#define ISAPNP_CONFIG_IO_DESC3    0x66  // I/O port descriptor 3
-#define ISAPNP_CONFIG_IO_DESC4    0x68  // I/O port descriptor 4
-#define ISAPNP_CONFIG_IO_DESC5    0x6A  // I/O port descriptor 5
-#define ISAPNP_CONFIG_IO_DESC6    0x6C  // I/O port descriptor 6
-#define ISAPNP_CONFIG_IO_DESC7    0x6E  // I/O port descriptor 7
-
-#define ISAPNP_CONFIG_IRQ_LEVEL0    0x70  // Interupt level for descriptor 0
-#define ISAPNP_CONFIG_IRQ_TYPE0     0x71  // Type level for descriptor 0
-#define ISAPNP_CONFIG_IRQ_LEVEL1    0x72  // Interupt level for descriptor 1
-#define ISAPNP_CONFIG_IRQ_TYPE1     0x73  // Type level for descriptor 1
-
-#define ISAPNP_CONFIG_DMA_CHANNEL0    0x74  // DMA channel for descriptor 0
-#define ISAPNP_CONFIG_DMA_CHANNEL1    0x75  // DMA channel for descriptor 1
-
-
-typedef struct _PNPISA_SERIAL_ID
-{
-  UCHAR VendorId[4];    // Vendor Identifier
-  UCHAR SerialId[4];    // Serial number
-  UCHAR Checksum;       // Checksum
-} PNPISA_SERIAL_ID, *PPNPISA_SERIAL_ID;
-
-
-#define ISAPNP_RES_PRIORITY_PREFERRED   0
-#define ISAPNP_RES_PRIORITY_ACCEPTABLE  1
-#define ISAPNP_RES_PRIORITY_FUNCTIONAL  2
-#define ISAPNP_RES_PRIORITY_INVALID        65535
-
-
-#define ISAPNP_RESOURCE_ITEM_TYPE   0x80      // 0 = small, 1 = large
-
-// Small Resource Item Names (SRINs)
-#define ISAPNP_SRIN_VERSION           0x1   // PnP version number
-#define ISAPNP_SRIN_LDEVICE_ID        0x2   // Logical device id
-#define ISAPNP_SRIN_CDEVICE_ID        0x3   // Compatible device id
-#define ISAPNP_SRIN_IRQ_FORMAT        0x4   // IRQ format
-#define ISAPNP_SRIN_DMA_FORMAT        0x5   // DMA format
-#define ISAPNP_SRIN_START_DFUNCTION   0x6   // Start dependant function
-#define ISAPNP_SRIN_END_DFUNCTION     0x7   // End dependant function
-#define ISAPNP_SRIN_IO_DESCRIPTOR     0x8   // I/O port descriptor
-#define ISAPNP_SRIN_FL_IO_DESCRIPOTOR 0x9   // Fixed location I/O port descriptor
-#define ISAPNP_SRIN_VENDOR_DEFINED    0xE   // Vendor defined
-#define ISAPNP_SRIN_END_TAG           0xF   // End tag
-
-typedef struct _ISAPNP_SRI_VERSION
-{
-  UCHAR Header;
-  UCHAR Version;        // Packed BCD format version number
-  UCHAR VendorVersion;  // Vendor specific version number
-} ISAPNP_SRI_VERSION, *PISAPNP_SRI_VERSION;
-
-typedef struct _ISAPNP_SRI_LDEVICE_ID
-{
-  UCHAR Header;
-  USHORT DeviceId;    // Logical device id
-  USHORT VendorId;    // Manufacturer id
-  UCHAR Flags;        // Flags
-} ISAPNP_SRI_LDEVICE_ID, *PISAPNP_SRI_LDEVICE_ID;
-
-typedef struct _ISAPNP_SRI_CDEVICE_ID
-{
-  UCHAR Header;
-  USHORT DeviceId;    // Logical device id
-  USHORT VendorId;    // Manufacturer id
-} ISAPNP_SRI_CDEVICE_ID, *PISAPNP_SRI_CDEVICE_ID;
-
-typedef struct _ISAPNP_SRI_IRQ_FORMAT
-{
-  UCHAR Header;
-  USHORT Mask;          // IRQ mask (bit 0 = irq 0, etc.)
-  UCHAR Information;    // IRQ information
-} ISAPNP_SRI_IRQ_FORMAT, *PISAPNP_SRI_IRQ_FORMAT;
-
-typedef struct _ISAPNP_SRI_DMA_FORMAT
-{
-  UCHAR Header;
-  USHORT Mask;          // DMA channel mask (bit 0 = channel 0, etc.)
-  UCHAR  Information;   // DMA information
-} ISAPNP_SRI_DMA_FORMAT, *PISAPNP_SRI_DMA_FORMAT;
-
-typedef struct _ISAPNP_SRI_START_DFUNCTION
-{
-  UCHAR Header;
-} ISAPNP_SRI_START_DFUNCTION, *PISAPNP_SRI_START_DFUNCTION;
-
-typedef struct _ISAPNP_SRI_END_DFUNCTION
-{
-  UCHAR Header;
-} ISAPNP_SRI_END_DFUNCTION, *PISAPNP_SRI_END_DFUNCTION;
-
-typedef struct _ISAPNP_SRI_IO_DESCRIPTOR
-{
-  UCHAR Header;
-  UCHAR Information;    // Information
-  USHORT RangeMinBase;  // Minimum base address
-  USHORT RangeMaxBase;  // Maximum base address
-  UCHAR Alignment;      // Base alignment
-  UCHAR RangeLength;    // Length of range
-} ISAPNP_SRI_IO_DESCRIPTOR, *PISAPNP_SRI_IO_DESCRIPTOR;
-
-typedef struct _ISAPNP_SRI_FL_IO_DESCRIPTOR
-{
-  UCHAR Header;
-  USHORT RangeBase;     // Range base address
-  UCHAR RangeLength;    // Length of range
-} ISAPNP_SRI_FL_IO_DESCRIPTOR, *PISAPNP_SRI_FL_IO_DESCRIPTOR;
-
-typedef struct _PISAPNP_SRI_VENDOR_DEFINED
-{
-  UCHAR Header;
-  UCHAR Reserved[0];  // Vendor defined
-} ISAPNP_SRI_VENDOR_DEFINED, *PISAPNP_SRI_VENDOR_DEFINED;
-
-typedef struct _ISAPNP_SRI_END_TAG
-{
-  UCHAR Header;
-  UCHAR Checksum;   // Checksum
-} ISAPNP_SRI_END_TAG, *PISAPNP_SRI_END_TAG;
-
-
-typedef struct _ISAPNP_LRI
-{
-  UCHAR Header;
-  USHORT Length;    // Length of data items
-} ISAPNP_LRI, *PISAPNP_LRI;
-
-// Large Resource Item Names (LRINs)
-#define ISAPNP_LRIN_MEMORY_RANGE      0x1   // Memory range descriptor
-#define ISAPNP_LRIN_ID_STRING_ANSI    0x2   // Identifier string (ANSI)
-#define ISAPNP_LRIN_ID_STRING_UNICODE 0x3   // Identifier string (UNICODE)
-#define ISAPNP_LRIN_VENDOR_DEFINED    0x4   // Vendor defined
-#define ISAPNP_LRIN_MEMORY_RANGE32    0x5   // 32-bit memory range descriptor
-#define ISAPNP_LRIN_FL_MEMORY_RANGE32 0x6   // 32-bit fixed location memory range descriptor
-
-typedef struct _ISAPNP_LRI_MEMORY_RANGE
-{
-  UCHAR Header;
-  USHORT Length;        // Length of data items
-  UCHAR Information;    // Information
-  USHORT RangeMinBase;  // Minimum base address
-  USHORT RangeMaxBase;  // Maximum base address
-  USHORT Alignment;     // Base alignment
-  USHORT RangeLength;   // Length of range
-} ISAPNP_LRI_MEMORY_RANGE, *PISAPNP_LRI_MEMORY_RANGE;
-
-typedef struct _ISAPNP_LRI_ID_STRING_ANSI
-{
-  UCHAR Header;
-  USHORT Length;        // Length of data items
-  UCHAR String[0];      // Identifier string
-} ISAPNP_LRI_ID_STRING_ANSI, *PISAPNP_LRI_ID_STRING_ANSI;
-
-typedef struct _ISAPNP_LRI_ID_STRING_UNICODE
-{
-  UCHAR Header;
-  USHORT Length;        // Length of data items
-  USHORT CountryId;     // Country identifier
-  USHORT String[0];     // Identifier string
-} ISAPNP_LRI_ID_STRING_UNICODE, *PISAPNP_LRI_ID_STRING_UNICODE;
-
-typedef struct _PISAPNP_LRI_VENDOR_DEFINED
-{
-  UCHAR Header;
-  USHORT Length;        // Length of data items
-  UCHAR Reserved[0];    // Vendor defined
-} ISAPNP_LRI_VENDOR_DEFINED, *PISAPNP_LRI_VENDOR_DEFINED;
+typedef enum {
+  dsStopped,
+  dsStarted
+} ISAPNP_DEVICE_STATE;
 
-typedef struct _ISAPNP_LRI_MEMORY_RANGE32
-{
-  UCHAR Header;
-  USHORT Length;        // Length of data items
-  UCHAR Information;    // Information
-  ULONG RangeMinBase;   // Minimum base address
-  ULONG RangeMaxBase;   // Maximum base address
-  ULONG Alignment;      // Base alignment
-  ULONG RangeLength;    // Length of range
-} ISAPNP_LRI_MEMORY_RANGE32, *PISAPNP_LRI_MEMORY_RANGE32;
+typedef struct _ISAPNP_COMMON_EXTENSION {
+  PDEVICE_OBJECT Self;
+  BOOLEAN IsFdo;
+  ISAPNP_DEVICE_STATE State;
+} ISAPNP_COMMON_EXTENSION, *PISAPNP_COMMON_EXTENSION;
 
-typedef struct _ISAPNP_LRI_FL_MEMORY_RANGE32
-{
-  UCHAR Header;
-  USHORT Length;        // Length of data items
-  UCHAR Information;    // Information
-  ULONG RangeMinBase;   // Minimum base address
-  ULONG RangeMaxBase;   // Maximum base address
-  ULONG RangeLength;    // Length of range
-} ISAPNP_LRI_FL_MEMORY_RANGE32, *PISAPNP_LRI_FL_MEMORY_RANGE32;
+typedef struct _ISAPNP_FDO_EXTENSION {
+  ISAPNP_COMMON_EXTENSION Common;
+  PDEVICE_OBJECT Ldo;
+  PDEVICE_OBJECT Pdo;
+  LIST_ENTRY DeviceListHead;
+  ULONG DeviceCount;
+  PUCHAR ReadDataPort;
+  KSPIN_LOCK Lock;
+} ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION;
 
-typedef struct _ISAPNP_CARD
-{
-  LIST_ENTRY ListEntry;
-  USHORT CardId;
+typedef struct _ISAPNP_LOGICAL_DEVICE {
+  ISAPNP_COMMON_EXTENSION Common;
   USHORT VendorId;
-  USHORT DeviceId;
-  ULONG Serial;
-  UCHAR PNPVersion;
-  UCHAR ProductVersion;
-  UNICODE_STRING Name;
-  LIST_ENTRY LogicalDevices;
-  KSPIN_LOCK LogicalDevicesLock;
-} ISAPNP_CARD, *PISAPNP_CARD;
-
-
-typedef struct _ISAPNP_DESCRIPTOR
-{
+  USHORT ProdId;
+  USHORT IoAddr;
+  UCHAR IrqNo;
+  UCHAR CSN;
+  UCHAR LDN;
   LIST_ENTRY ListEntry;
-  IO_RESOURCE_DESCRIPTOR Descriptor;
-} ISAPNP_DESCRIPTOR, *PISAPNP_DESCRIPTOR;
+} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
 
-typedef struct _ISAPNP_CONFIGURATION_LIST
-{
-  LIST_ENTRY ListEntry;
-  ULONG Priority;
-  LIST_ENTRY ListHead;
-} ISAPNP_CONFIGURATION_LIST, *PISAPNP_CONFIGURATION_LIST;
+/* isapnp.c */
+NTSTATUS
+NTAPI
+DriverEntry(
+  IN PDRIVER_OBJECT DriverObject,
+  IN PUNICODE_STRING RegistryPath);
 
+NTSTATUS
+NTAPI
+IsaForwardIrpSynchronous(
+       IN PISAPNP_FDO_EXTENSION FdoExt,
+       IN PIRP Irp);
 
-#define MAX_COMPATIBLE_ID   32
+/* fdo.c */
+NTSTATUS
+NTAPI
+IsaFdoPnp(
+  IN PISAPNP_FDO_EXTENSION FdoExt,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp);
 
-typedef struct _ISAPNP_LOGICAL_DEVICE
-{
-  LIST_ENTRY CardListEntry;
-  LIST_ENTRY DeviceListEntry;
-  USHORT Number;
-  USHORT VendorId;
-  USHORT DeviceId;
-  USHORT CVendorId[MAX_COMPATIBLE_ID];
-  USHORT CDeviceId[MAX_COMPATIBLE_ID];
-  USHORT Regs;
-  PISAPNP_CARD Card;
-  UNICODE_STRING Name;
-  PDEVICE_OBJECT Pdo;
-  PIO_RESOURCE_REQUIREMENTS_LIST ResourceLists;
-  LIST_ENTRY Configuration;
-  ULONG ConfigurationSize;
-  ULONG DescriptorCount;
-  ULONG CurrentDescriptorCount;
-} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
+/* pdo.c */
+NTSTATUS
+NTAPI
+IsaPdoPnp(
+  IN PISAPNP_LOGICAL_DEVICE LogDev,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp);
 
+/* hardware.c */
+NTSTATUS
+NTAPI
+IsaHwDetectReadDataPort(
+  IN PISAPNP_FDO_EXTENSION FdoExt);
 
-typedef enum {
-  dsStopped,
-  dsStarted
-} ISAPNP_DEVICE_STATE;
+NTSTATUS
+NTAPI
+IsaHwFillDeviceList(
+  IN PISAPNP_FDO_EXTENSION FdoExt);
 
-typedef struct _ISAPNP_DEVICE_EXTENSION
-{
-  // Physical Device Object
-  PDEVICE_OBJECT Pdo;
-  // Lower device object
-  PDEVICE_OBJECT Ldo;
-  // List of ISA PnP cards managed by this driver
-  LIST_ENTRY CardListHead;
-  // List of devices managed by this driver
-  LIST_ENTRY DeviceListHead;
-  // Number of devices managed by this driver
-  ULONG DeviceListCount;
-  // Spinlock for the linked lists
-  KSPIN_LOCK GlobalListLock;
-  // Current state of the driver
-  ISAPNP_DEVICE_STATE State;
-} ISAPNP_DEVICE_EXTENSION, *PISAPNP_DEVICE_EXTENSION;
+NTSTATUS
+NTAPI
+IsaHwDeactivateDevice(
+  IN PISAPNP_LOGICAL_DEVICE LogicalDevice);
 
 NTSTATUS
 NTAPI
-DriverEntry(
-  IN PDRIVER_OBJECT DriverObject,
-  IN PUNICODE_STRING RegistryPath);
+IsaHwActivateDevice(
+  IN PISAPNP_LOGICAL_DEVICE LogicalDevice);
 
 #ifdef __cplusplus
 }
index b0b7919..bc8a96a 100644 (file)
@@ -1,9 +1,13 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="isapnp" type="kernelmodedriver" installbase="system32/drivers" installname="isapnp.sys">
+       <bootstrap installbase="$(CDOUTPUT)"/>
        <include base="isapnp">.</include>
        <library>ntoskrnl</library>
        <library>hal</library>
        <file>isapnp.c</file>
+       <file>pdo.c</file>
+       <file>fdo.c</file>
+       <file>hardware.c</file>
        <file>isapnp.rc</file>
 </module>
diff --git a/drivers/bus/isapnp/isapnphw.h b/drivers/bus/isapnp/isapnphw.h
new file mode 100644 (file)
index 0000000..aec8719
--- /dev/null
@@ -0,0 +1,106 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ISAPNP_ADDRESS 0x279
+#define ISAPNP_WRITE_DATA 0xA79
+
+#define ISAPNP_READ_PORT_MIN 0x203
+#define ISAPNP_READ_PORT_START 0x213
+#define ISAPNP_READ_PORT_MAX 0x3FF
+#define ISAPNP_READ_PORT_STEP 0x10
+
+#define ISAPNP_CSN_MIN 0x01
+#define ISAPNP_CSN_MAX 0x0F
+
+#define ISAPNP_READPORT 0x00
+#define ISAPNP_SERIALISOLATION 0x01
+#define ISAPNP_CONFIGCONTROL 0x02
+#define ISAPNP_WAKE 0x03
+#define ISAPNP_RESOURCEDATA 0x04
+#define ISAPNP_STATUS 0x05
+#define ISAPNP_CARDSELECTNUMBER 0x06
+#define ISAPNP_LOGICALDEVICENUMBER 0x07
+
+#define ISAPNP_ACTIVATE 0x30
+#define ISAPNP_IORANGECHECK 0x31
+
+#define ISAPNP_IOBASE(n) (0x60 + ((n)*2))
+#define ISAPNP_IRQNO(n) (0x70 + ((n)*2))
+#define ISAPNP_IRQTYPE(n) (0x71 + ((n) * 2))
+
+#define ISAPNP_CONFIG_RESET (1 << 0)
+#define ISAPNP_CONFIG_WAIT_FOR_KEY (1 << 1)
+#define ISAPNP_CONFIG_RESET_CSN (1 << 2)
+
+#define ISAPNP_LFSR_SEED 0x6A
+
+#define ISAPNP_IS_SMALL_TAG(t) (!((t) & 0x80))
+#define ISAPNP_SMALL_TAG_NAME(t) (((t) >> 3) & 0xF)
+#define ISAPNP_SMALL_TAG_LEN(t) (((t) & 0x7))
+#define ISAPNP_TAG_PNPVERNO 0x01
+#define ISAPNP_TAG_LOGDEVID 0x02
+#define ISAPNP_TAG_COMPATDEVID 0x03
+#define ISAPNP_TAG_IRQ 0x04
+#define ISAPNP_TAG_DMA 0x05
+#define ISAPNP_TAG_STARTDEP 0x06
+#define ISAPNP_TAG_ENDDEP 0x07
+#define ISAPNP_TAG_IOPORT 0x08
+#define ISAPNP_TAG_FIXEDIO 0x09
+#define ISAPNP_TAG_RSVDSHORTA 0x0A
+#define ISAPNP_TAG_RSVDSHORTB 0x0B
+#define ISAPNP_TAG_RSVDSHORTC 0x0C
+#define ISAPNP_TAG_RSVDSHORTD 0x0D
+#define ISAPNP_TAG_VENDORSHORT 0x0E
+#define ISAPNP_TAG_END 0x0F
+
+#define ISAPNP_IS_LARGE_TAG(t) (((t) & 0x80))
+#define ISAPNP_LARGE_TAG_NAME(t) (t)
+#define ISAPNP_TAG_MEMRANGE 0x81
+#define ISAPNP_TAG_ANSISTR 0x82
+#define ISAPNP_TAG_UNICODESTR 0x83
+#define ISAPNP_TAG_VENDORLONG 0x84
+#define ISAPNP_TAG_MEM32RANGE 0x85
+#define ISAPNP_TAG_FIXEDMEM32RANGE 0x86
+#define ISAPNP_TAG_RSVDLONG0 0xF0
+#define ISAPNP_TAG_RSVDLONG1 0xF1
+#define ISAPNP_TAG_RSVDLONG2 0xF2
+#define ISAPNP_TAG_RSVDLONG3 0xF3
+#define ISAPNP_TAG_RSVDLONG4 0xF4
+#define ISAPNP_TAG_RSVDLONG5 0xF5
+#define ISAPNP_TAG_RSVDLONG6 0xF6
+#define ISAPNP_TAG_RSVDLONG7 0xF7
+#define ISAPNP_TAG_RSVDLONG8 0xF8
+#define ISAPNP_TAG_RSVDLONG9 0xF9
+#define ISAPNP_TAG_RSVDLONGA 0xFA
+#define ISAPNP_TAG_RSVDLONGB 0xFB
+#define ISAPNP_TAG_RSVDLONGC 0xFC
+#define ISAPNP_TAG_RSVDLONGD 0xFD
+#define ISAPNP_TAG_RSVDLONGE 0xFE
+#define ISAPNP_TAG_RSVDLONGF 0xFF
+#define ISAPNP_TAG_PSEUDO_NEWBOARD 0x100
+
+typedef struct _ISAPNP_IDENTIFIER {
+  USHORT VendorId;
+  USHORT ProdId;
+  ULONG Serial;
+  UCHAR Checksum;
+} ISAPNP_IDENTIFIER, *PISAPNP_IDENTIFIER;
+
+typedef struct _ISAPNP_LOGDEVID {
+  USHORT VendorId;
+  USHORT ProdId;
+  USHORT Flags;
+} ISAPNP_LOGDEVID, *PISAPNP_LOGDEVID;
+
+typedef struct _ISAPNP_DEVICEID {
+  CHAR* Name;
+  USHORT VendorId;
+  USHORT ProdId;
+} ISAPNP_DEVICEID, *PISAPNP_DEVICEID;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
new file mode 100644 (file)
index 0000000..0292f20
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * PROJECT:         ReactOS ISA PnP Bus driver
+ * FILE:            pdo.c
+ * PURPOSE:         PDO-specific code
+ * PROGRAMMERS:     Cameron Gutman (cameron.gutman@reactos.org)
+ */
+#include <isapnp.h>
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS
+NTAPI
+IsaPdoQueryDeviceRelations(
+  IN PISAPNP_LOGICAL_DEVICE LogDev,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp)
+{
+  PDEVICE_RELATIONS DeviceRelations;
+
+  if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
+      return Irp->IoStatus.Status;
+
+  DeviceRelations = ExAllocatePool(PagedPool, sizeof(*DeviceRelations));
+  if (!DeviceRelations)
+      return STATUS_INSUFFICIENT_RESOURCES;
+
+  DeviceRelations->Count = 1;
+  DeviceRelations->Objects[0] = LogDev->Common.Self;
+  ObReferenceObject(LogDev->Common.Self);
+
+  Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
+
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IsaPdoPnp(
+  IN PISAPNP_LOGICAL_DEVICE LogDev,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp)
+{
+  NTSTATUS Status = Irp->IoStatus.Status;
+
+  switch (IrpSp->MinorFunction)
+  {
+     case IRP_MN_START_DEVICE:
+       Status = IsaHwActivateDevice(LogDev);
+
+       if (NT_SUCCESS(Status))
+           LogDev->Common.State = dsStarted;
+       break;
+
+     case IRP_MN_STOP_DEVICE:
+       Status = IsaHwDeactivateDevice(LogDev);
+
+       if (NT_SUCCESS(Status))
+           LogDev->Common.State = dsStopped;
+       break;
+
+     case IRP_MN_QUERY_DEVICE_RELATIONS:
+       Status = IsaPdoQueryDeviceRelations(LogDev, Irp, IrpSp);
+       break;
+
+     case IRP_MN_QUERY_RESOURCES:
+       DPRINT1("IRP_MN_QUERY_RESOURCES is UNIMPLEMENTED!\n");
+       break;
+
+     case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
+       DPRINT1("IRP_MN_QUERY_RESOURCE_REQUIREMENTS is UNIMPLEMENTED!\n");
+       break;
+
+     default:
+       DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction);
+       break;
+  }
+
+  Irp->IoStatus.Status = Status;
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+  return Status;
+}
index 35fd125..b6753e1 100644 (file)
 
 /*** PRIVATE *****************************************************************/
 
+static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion;
+
+static NTSTATUS NTAPI
+ForwardIrpAndWaitCompletion(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp,
+       IN PVOID Context)
+{
+       UNREFERENCED_PARAMETER(DeviceObject);
+       if (Irp->PendingReturned)
+               KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
+       return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS NTAPI
+ForwardIrpAndWait(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       KEVENT Event;
+       NTSTATUS Status;
+       PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Ldo;
+       ASSERT(LowerDevice);
+
+       KeInitializeEvent(&Event, NotificationEvent, FALSE);
+       IoCopyCurrentIrpStackLocationToNext(Irp);
+
+       IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
+
+       Status = IoCallDriver(LowerDevice, Irp);
+       if (Status == STATUS_PENDING)
+       {
+               Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+               if (NT_SUCCESS(Status))
+                       Status = Irp->IoStatus.Status;
+       }
+
+       return Status;
+}
+
 static NTSTATUS
 FdoLocateChildDevice(
   PPCI_DEVICE *Device,
@@ -239,8 +279,6 @@ FdoQueryBusRelations(
         break;
       }
 
-      Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
-
       Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
       //Device->Pdo->Flags |= DO_POWER_PAGABLE;
@@ -468,7 +506,7 @@ FdoPnpControl(
 {
   PFDO_DEVICE_EXTENSION DeviceExtension;
   PIO_STACK_LOCATION IrpSp;
-  NTSTATUS Status;
+  NTSTATUS Status = Irp->IoStatus.Status;
 
   DPRINT("Called\n");
 
@@ -494,8 +532,13 @@ FdoPnpControl(
     break;
 #endif
   case IRP_MN_QUERY_DEVICE_RELATIONS:
+    if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
+        break;
+
     Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp);
-    break;
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
 #if 0
   case IRP_MN_QUERY_PNP_DEVICE_STATE:
     Status = STATUS_NOT_IMPLEMENTED;
@@ -515,38 +558,37 @@ FdoPnpControl(
 #endif
   case IRP_MN_START_DEVICE:
     DPRINT("IRP_MN_START_DEVICE received\n");
-    Status = FdoStartDevice(DeviceObject, Irp);
-    break;
+    Status = ForwardIrpAndWait(DeviceObject, Irp);
+    if (NT_SUCCESS(Status))
+       Status = FdoStartDevice(DeviceObject, Irp);
+
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
   case IRP_MN_STOP_DEVICE:
     /* Currently not supported */
     Status = STATUS_UNSUCCESSFUL;
-    break;
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
 #if 0
   case IRP_MN_SURPRISE_REMOVAL:
     Status = STATUS_NOT_IMPLEMENTED;
     break;
 #endif
+  case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
+    break;
+  case IRP_MN_REMOVE_DEVICE:
+    DPRINT1("IRP_MN_REMOVE_DEVICE is UNIMPLEMENTED!\n");
+    break;
   default:
     DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction);
-    /* fall through */
-
-  case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
-    /*
-     * Do NOT complete the IRP as it will be processed by the lower
-     * device object, which will complete the IRP
-     */
-    IoSkipCurrentIrpStackLocation(Irp);
-    Status = IoCallDriver(DeviceExtension->Ldo, Irp);
-    return Status;
     break;
   }
 
-
-  if (Status != STATUS_PENDING) {
-    if (Status != STATUS_NOT_IMPLEMENTED)
-      Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-  }
+  Irp->IoStatus.Status = Status;
+  IoSkipCurrentIrpStackLocation(Irp);
+  Status = IoCallDriver(DeviceExtension->Ldo, Irp);
 
   DPRINT("Leaving. Status 0x%X\n", Status);
 
index f19e45c..e5961fb 100644 (file)
@@ -413,8 +413,8 @@ PdoQueryResourceRequirements(
   RtlZeroMemory(ResourceList, ListSize);
   ResourceList->ListSize = ListSize;
   ResourceList->InterfaceType = PCIBus;
-  ResourceList->BusNumber = 0;
-  ResourceList->SlotNumber = 0;
+  ResourceList->BusNumber = DeviceExtension->PciDevice->BusNumber;
+  ResourceList->SlotNumber = DeviceExtension->PciDevice->SlotNumber.u.AsULONG;
   ResourceList->AlternativeLists = 1;
 
   ResourceList->List[0].Version = 1;
@@ -717,7 +717,7 @@ PdoQueryResources(
   RtlZeroMemory(ResourceList, ListSize);
   ResourceList->Count = 1;
   ResourceList->List[0].InterfaceType = PCIBus;
-  ResourceList->List[0].BusNumber = 0;
+  ResourceList->List[0].BusNumber = DeviceExtension->PciDevice->BusNumber;
 
   PartialList = &ResourceList->List[0].PartialResourceList;
   PartialList->Version = 1;
@@ -775,7 +775,7 @@ PdoQueryResources(
       Descriptor->ShareDisposition = CmResourceShareShared;
       Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
       Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine;
-      Descriptor->u.Interrupt.Vector = 0;
+      Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine;
       Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
     }
   }
@@ -1186,6 +1186,52 @@ PdoQueryInterface(
   return Status;
 }
 
+static NTSTATUS
+PdoStartDevice(
+  IN PDEVICE_OBJECT DeviceObject,
+  IN PIRP Irp,
+  PIO_STACK_LOCATION IrpSp)
+{
+  PCM_RESOURCE_LIST RawResList = IrpSp->Parameters.StartDevice.AllocatedResources;
+  PCM_FULL_RESOURCE_DESCRIPTOR RawFullDesc;
+  PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDesc;
+  ULONG i, ii;
+  PPDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+  UCHAR Irq;
+
+  if (!RawResList)
+      return STATUS_SUCCESS;
+
+  /* TODO: Assign the other resources we get to the card */
+
+  for (i = 0; i < RawResList->Count; i++)
+  {
+      RawFullDesc = &RawResList->List[i];
+
+      for (ii = 0; ii < RawFullDesc->PartialResourceList.Count; ii++)
+      {
+          RawPartialDesc = &RawFullDesc->PartialResourceList.PartialDescriptors[ii];
+
+          if (RawPartialDesc->Type == CmResourceTypeInterrupt)
+          {
+              DPRINT1("Assigning IRQ %x to PCI device (%x, %x)\n",
+                      RawPartialDesc->u.Interrupt.Vector,
+                      DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+                      DeviceExtension->PciDevice->BusNumber);
+
+              Irq = (UCHAR)RawPartialDesc->u.Interrupt.Vector;
+              HalSetBusDataByOffset(PCIConfiguration,
+                                    DeviceExtension->PciDevice->BusNumber,
+                                    DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+                                    &Irq,
+                                    0x3c /* PCI_INTERRUPT_LINE */,
+                                    sizeof(UCHAR));
+          }
+      }
+   }
+
+   return STATUS_SUCCESS;
+}
 
 static NTSTATUS
 PdoReadConfig(
@@ -1247,6 +1293,33 @@ PdoWriteConfig(
   return STATUS_SUCCESS;
 }
 
+static NTSTATUS
+PdoQueryDeviceRelations(
+  IN PDEVICE_OBJECT DeviceObject,
+  IN PIRP Irp,
+  PIO_STACK_LOCATION IrpSp)
+{
+  PDEVICE_RELATIONS DeviceRelations;
+
+  /* We only support TargetDeviceRelation for child PDOs */
+  if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
+      return Irp->IoStatus.Status;
+
+  /* We can do this because we only return 1 PDO for TargetDeviceRelation */
+  DeviceRelations = ExAllocatePool(PagedPool, sizeof(*DeviceRelations));
+  if (!DeviceRelations)
+      return STATUS_INSUFFICIENT_RESOURCES;
+
+  DeviceRelations->Count = 1;
+  DeviceRelations->Objects[0] = DeviceObject;
+
+  /* The PnP manager will remove this when it is done with the PDO */
+  ObReferenceObject(DeviceObject);
+
+  Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
+
+  return STATUS_SUCCESS;
+}
 
 static NTSTATUS
 PdoSetPower(
@@ -1319,8 +1392,7 @@ PdoPnpControl(
     break;
 
   case IRP_MN_QUERY_DEVICE_RELATIONS:
-    /* FIXME: Possibly handle for RemovalRelations */
-    DPRINT("Unimplemented IRP_MN_QUERY_DEVICE_RELATIONS received\n");
+    Status = PdoQueryDeviceRelations(DeviceObject, Irp, IrpSp);
     break;
 
   case IRP_MN_QUERY_DEVICE_TEXT:
@@ -1352,6 +1424,9 @@ PdoPnpControl(
     break;
 
   case IRP_MN_START_DEVICE:
+    Status = PdoStartDevice(DeviceObject, Irp, IrpSp);
+    break;
+
   case IRP_MN_QUERY_STOP_DEVICE:
   case IRP_MN_CANCEL_STOP_DEVICE:
   case IRP_MN_STOP_DEVICE:
diff --git a/drivers/bus/pcmcia/fdo.c b/drivers/bus/pcmcia/fdo.c
new file mode 100644 (file)
index 0000000..348fd1c
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS Kernel
+ * FILE:        drivers/bus/pcmcia/fdo.c
+ * PURPOSE:     PCMCIA Bus Driver
+ * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
+ */
+
+#include <pcmcia.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+NTSTATUS
+NTAPI
+PcmciaFdoPlugPlay(PPCMCIA_FDO_EXTENSION FdoExt,
+                  PIRP Irp)
+{
+  UNIMPLEMENTED
+
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+  return STATUS_NOT_SUPPORTED;
+}
+
diff --git a/drivers/bus/pcmcia/pcmcia.c b/drivers/bus/pcmcia/pcmcia.c
new file mode 100644 (file)
index 0000000..54d23da
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS Kernel
+ * FILE:        drivers/bus/pcmcia/pcmcia.c
+ * PURPOSE:     PCMCIA Bus Driver
+ * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
+ */
+
+#include <pcmcia.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+BOOLEAN IoctlEnabled;
+
+NTSTATUS
+NTAPI
+PcmciaCreateClose(PDEVICE_OBJECT DeviceObject,
+                  PIRP Irp)
+{
+  Irp->IoStatus.Status = STATUS_SUCCESS;
+  Irp->IoStatus.Information = 0;
+
+  DPRINT("PCMCIA: Create/Close\n");
+
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+PcmciaDeviceControl(PDEVICE_OBJECT DeviceObject,
+                    PIRP Irp)
+{
+  PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+  NTSTATUS Status;
+
+  DPRINT("PCMCIA: DeviceIoControl\n");
+
+  Irp->IoStatus.Information = 0;
+
+  switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
+  {
+     default:
+       DPRINT1("PCMCIA: Unknown ioctl code: %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
+       Status = STATUS_NOT_SUPPORTED;
+  }
+
+  Irp->IoStatus.Status = Status;
+
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+  return Status;
+}
+
+VOID
+NTAPI
+PcmciaUnload(PDRIVER_OBJECT DriverObject)
+{
+  DPRINT("PCMCIA: Unload\n");
+}
+
+NTSTATUS
+NTAPI
+PcmciaPlugPlay(PDEVICE_OBJECT DeviceObject,
+               PIRP Irp)
+{
+  PPCMCIA_COMMON_EXTENSION Common = DeviceObject->DeviceExtension;
+
+  DPRINT("PCMCIA: PnP\n");
+  if (Common->IsFDO)
+  {
+     return PcmciaFdoPlugPlay((PPCMCIA_FDO_EXTENSION)Common,
+                              Irp);
+  }
+  else
+  {
+     return PcmciaPdoPlugPlay((PPCMCIA_PDO_EXTENSION)Common,
+                              Irp);
+  }
+}
+
+NTSTATUS
+NTAPI
+PcmciaPower(PDEVICE_OBJECT DeviceObject,
+            PIRP Irp)
+{
+  PPCMCIA_COMMON_EXTENSION Common = DeviceObject->DeviceExtension;
+  PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+  NTSTATUS Status;
+
+  switch (IrpSp->MinorFunction)
+  {
+     case IRP_MN_QUERY_POWER:
+       /* I don't see any reason that we should care */
+       DPRINT("PCMCIA: IRP_MN_QUERY_POWER\n");
+       Status = STATUS_SUCCESS;
+       break;
+
+     case IRP_MN_POWER_SEQUENCE:
+       DPRINT("PCMCIA: IRP_MN_POWER_SEQUENCE\n");
+       RtlCopyMemory(IrpSp->Parameters.PowerSequence.PowerSequence,
+                     &Common->PowerSequence,
+                     sizeof(POWER_SEQUENCE));
+       Status = STATUS_SUCCESS;
+       break;
+
+     case IRP_MN_WAIT_WAKE:
+       /* Not really sure about this */
+       DPRINT("PCMCIA: IRP_MN_WAIT_WAKE\n");
+       Status = STATUS_NOT_SUPPORTED;
+       break;
+
+     case IRP_MN_SET_POWER:
+       DPRINT("PCMCIA: IRP_MN_SET_POWER\n");
+       if (IrpSp->Parameters.Power.Type == SystemPowerState)
+       {
+          Common->SystemPowerState = IrpSp->Parameters.Power.State.SystemState;
+
+          Status = STATUS_SUCCESS;
+       }
+       else
+       {
+          Common->DevicePowerState = IrpSp->Parameters.Power.State.DeviceState;
+
+          /* Update the POWER_SEQUENCE struct */
+          if (Common->DevicePowerState <= PowerDeviceD1)
+              Common->PowerSequence.SequenceD1++;
+
+          if (Common->DevicePowerState <= PowerDeviceD2)
+              Common->PowerSequence.SequenceD2++;
+
+          if (Common->DevicePowerState <= PowerDeviceD3)
+              Common->PowerSequence.SequenceD3++;
+
+          /* Start the underlying device if we are handling this for a PDO */
+          if (!Common->IsFDO)
+              Status = PcmciaPdoSetPowerState((PPCMCIA_PDO_EXTENSION)Common);
+          else
+              Status = STATUS_SUCCESS;
+       }
+
+       /* Report that we changed state to the Power Manager */
+       PoSetPowerState(DeviceObject, IrpSp->Parameters.Power.Type, IrpSp->Parameters.Power.State);
+       break;
+
+     default:
+       DPRINT1("PCMCIA: Invalid MN code in MJ_POWER handler %x\n", IrpSp->MinorFunction);
+       ASSERT(FALSE);
+       Status = STATUS_INVALID_DEVICE_REQUEST;
+       break;
+  }
+
+  Irp->IoStatus.Status = Status;
+  Irp->IoStatus.Information = 0;
+
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+  return Status;
+}
+
+NTSTATUS
+NTAPI
+PcmciaAddDevice(PDRIVER_OBJECT DriverObject,
+                PDEVICE_OBJECT PhysicalDeviceObject)
+{
+  PPCMCIA_FDO_EXTENSION FdoExt;
+  PDEVICE_OBJECT Fdo;
+  NTSTATUS Status;
+
+  DPRINT("PCMCIA: AddDevice\n");
+
+  Status = IoCreateDevice(DriverObject,
+                          sizeof(*FdoExt),
+                          NULL,
+                          FILE_DEVICE_BUS_EXTENDER,
+                          FILE_DEVICE_SECURE_OPEN,
+                          FALSE,
+                          &Fdo);
+  if (!NT_SUCCESS(Status)) return Status;
+
+  FdoExt = Fdo->DeviceExtension;
+
+  RtlZeroMemory(FdoExt, sizeof(*FdoExt));
+
+  InitializeListHead(&FdoExt->ChildDeviceList);
+  KeInitializeSpinLock(&FdoExt->Lock);
+
+  FdoExt->Common.Self = Fdo;
+  FdoExt->Common.IsFDO = TRUE;
+  FdoExt->Common.State = dsStopped;
+
+  FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo,
+                                            PhysicalDeviceObject);
+
+  Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+DriverEntry(PDRIVER_OBJECT DriverObject,
+            PUNICODE_STRING RegistryPath)
+{
+  RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+  NTSTATUS Status;
+
+  DPRINT1("PCMCIA: DriverEntry\n");
+
+  DriverObject->MajorFunction[IRP_MJ_CREATE] = PcmciaCreateClose;
+  DriverObject->MajorFunction[IRP_MJ_CLOSE] = PcmciaCreateClose;
+  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PcmciaDeviceControl;
+  DriverObject->MajorFunction[IRP_MJ_PNP] = PcmciaPlugPlay;
+  DriverObject->MajorFunction[IRP_MJ_POWER] = PcmciaPower;
+
+  DriverObject->DriverExtension->AddDevice = PcmciaAddDevice;
+  DriverObject->DriverUnload = PcmciaUnload;
+
+  RtlZeroMemory(QueryTable, sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
+
+  QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+  QueryTable[0].Name = L"IoctlInterface";
+  QueryTable[0].EntryContext = &IoctlEnabled;
+
+  Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
+                                  L"Pcmcia\\Parameters",
+                                  QueryTable,
+                                  NULL,
+                                  NULL);
+  if (!NT_SUCCESS(Status))
+  {
+      /* Key not present so assume disabled */
+      IoctlEnabled = FALSE;
+  }
+
+  DPRINT("PCMCIA: Ioctl interface %s\n",
+         (IoctlEnabled ? "enabled" : "disabled"));
+
+  return STATUS_SUCCESS;
+}
diff --git a/drivers/bus/pcmcia/pcmcia.h b/drivers/bus/pcmcia/pcmcia.h
new file mode 100644 (file)
index 0000000..32dd5f2
--- /dev/null
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <ntifs.h>
+#include <wdmguid.h>
+#include <stdio.h>
+#include <ntddk.h>
+
+typedef enum {
+  dsStopped,
+  dsStarted,
+  dsPaused,
+  dsRemoved,
+  dsSurpriseRemoved
+} PCMCIA_DEVICE_STATE;
+
+typedef struct _PCMCIA_COMMON_EXTENSION {
+  PDEVICE_OBJECT Self;
+  BOOLEAN IsFDO;
+  POWER_SEQUENCE PowerSequence;
+  PCMCIA_DEVICE_STATE State;
+  DEVICE_POWER_STATE DevicePowerState;
+  SYSTEM_POWER_STATE SystemPowerState;
+} PCMCIA_COMMON_EXTENSION, *PPCMCIA_COMMON_EXTENSION;
+
+typedef struct _PCMCIA_PDO_EXTENSION {
+  PCMCIA_COMMON_EXTENSION Common;
+} PCMCIA_PDO_EXTENSION, *PPCMCIA_PDO_EXTENSION;
+
+typedef struct _PCMCIA_FDO_EXTENSION {
+  PCMCIA_COMMON_EXTENSION Common;
+  PDEVICE_OBJECT Ldo;
+  LIST_ENTRY ChildDeviceList;
+  KSPIN_LOCK Lock;
+} PCMCIA_FDO_EXTENSION, *PPCMCIA_FDO_EXTENSION;
+
+/* pdo.c */
+NTSTATUS
+NTAPI
+PcmciaPdoPlugPlay(PPCMCIA_PDO_EXTENSION PdoExt,
+                  PIRP Irp);
+
+NTSTATUS
+NTAPI
+PcmciaPdoSetPowerState(PPCMCIA_PDO_EXTENSION PdoExt);
+
+/* fdo.c */
+NTSTATUS
+NTAPI
+PcmciaFdoPlugPlay(PPCMCIA_FDO_EXTENSION FdoExt,
+                  PIRP Irp);
+
diff --git a/drivers/bus/pcmcia/pcmcia.rbuild b/drivers/bus/pcmcia/pcmcia.rbuild
new file mode 100644 (file)
index 0000000..2d33ce5
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<module name="pcmcia" type="kernelmodedriver" installbase="system32/drivers" installname="pcmcia.sys">
+       <bootstrap installbase="$(CDOUTPUT)" />
+       <include base="pcmcia">.</include>
+       <library>ntoskrnl</library>
+       <library>hal</library>
+       <file>fdo.c</file>
+       <file>pcmcia.c</file>
+       <file>pdo.c</file>
+       <file>pcmcia.rc</file>
+</module>
diff --git a/drivers/bus/pcmcia/pcmcia.rc b/drivers/bus/pcmcia/pcmcia.rc
new file mode 100644 (file)
index 0000000..1395816
--- /dev/null
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION   "PCMCIA Bus Driver\0"
+#define REACTOS_STR_INTERNAL_NAME      "pcmcia\0"
+#define REACTOS_STR_ORIGINAL_FILENAME  "pcmcia.sys\0"
+#include <reactos/version.rc>
diff --git a/drivers/bus/pcmcia/pdo.c b/drivers/bus/pcmcia/pdo.c
new file mode 100644 (file)
index 0000000..0e4d168
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS Kernel
+ * FILE:        drivers/bus/pcmcia/pdo.c
+ * PURPOSE:     PCMCIA Bus Driver
+ * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
+ */
+
+#include <pcmcia.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+NTSTATUS
+NTAPI
+PcmciaPdoPlugPlay(PPCMCIA_PDO_EXTENSION PdoExt,
+                  PIRP Irp)
+{
+  UNIMPLEMENTED
+
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+  return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PcmciaPdoSetPowerState(PPCMCIA_PDO_EXTENSION PdoExt)
+{
+  UNIMPLEMENTED
+
+  return STATUS_SUCCESS;
+}
+
index 3040a04..5a4970f 100644 (file)
@@ -251,7 +251,7 @@ IKsAllocator_fnDeviceIoControl(
         }
     }
 
-    /* unhandeled request */
+    /* unhandled request */
     Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
index ef83f9d..2067de5 100644 (file)
@@ -94,6 +94,8 @@ KsReleaseDeviceSecurityLock(
 {
     PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader;
 
+    DPRINT("KsReleaseDevice\n");
+
     ExReleaseResourceLite(&Header->SecurityLock);
     KeLeaveCriticalRegion();
 }
@@ -1589,7 +1591,7 @@ KsAcquireControl(
     /* sanity check */
     ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
 
-    KeWaitForSingleObject(&BasicHeader->ControlMutex, Executive, KernelMode, FALSE, NULL);
+    KeWaitForSingleObject(BasicHeader->ControlMutex, Executive, KernelMode, FALSE, NULL);
 
 }
 
@@ -1606,7 +1608,7 @@ KsReleaseControl(
     /* sanity check */
     ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
 
-    KeReleaseMutex(&BasicHeader->ControlMutex, FALSE);
+    KeReleaseMutex(BasicHeader->ControlMutex, FALSE);
 }
 
 
@@ -1623,11 +1625,11 @@ KsAcquireDevice(
     IKsDevice *KsDevice;
     PKSIDEVICE_HEADER DeviceHeader;
 
-
+    DPRINT("KsAcquireDevice\n");
     DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
 
     /* get device interface*/
-    KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
+    KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
 
     /* acquire device mutex */
     KsDevice->lpVtbl->AcquireDevice(KsDevice);
@@ -1645,7 +1647,7 @@ KsReleaseDevice(
     PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
 
     /* get device interface*/
-    KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
+    KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
 
     /* release device mutex */
     KsDevice->lpVtbl->ReleaseDevice(KsDevice);
@@ -1668,7 +1670,7 @@ KsTerminateDevice(
     DeviceHeader = DeviceExtension->DeviceHeader;
 
     /* get device interface*/
-    KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
+    KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
 
     /* now free device header */
     KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader);
@@ -1958,7 +1960,7 @@ KsDeviceGetBusData(
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 void
@@ -1969,7 +1971,12 @@ KsDeviceRegisterAdapterObject(
     IN ULONG MaxMappingsByteCount,
     IN ULONG MappingTableStride)
 {
-    UNIMPLEMENTED
+    PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
+
+    DeviceHeader->AdapterObject = AdapterObject;
+    DeviceHeader->MaxMappingsByteCount = MaxMappingsByteCount;
+    DeviceHeader->MappingTableStride = MappingTableStride;
+
 }
 
 /*
@@ -1982,6 +1989,7 @@ KsGetBusEnumIdentifier(
     IN PIRP Irp)
 {
     UNIMPLEMENTED
+
     return STATUS_UNSUCCESSFUL;
 }
 
@@ -2094,8 +2102,15 @@ KspCountMethodSets(
     if (!AutomationTableB)
         return AutomationTableA->MethodSetsCount;
 
-    /* sanity check */
-    ASSERT(AutomationTableA->MethodItemSize  == AutomationTableB->MethodItemSize);
+
+    DPRINT("AutomationTableA MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableA->MethodItemSize, AutomationTableA->MethodSetsCount);
+    DPRINT("AutomationTableB MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableB->MethodItemSize, AutomationTableB->MethodSetsCount);
+
+    if (AutomationTableA->MethodItemSize && AutomationTableB->MethodItemSize)
+    {
+        /* sanity check */
+        ASSERT(AutomationTableA->MethodItemSize  == AutomationTableB->MethodItemSize);
+    }
 
     /* now iterate all property sets and compare their guids */
     Count = AutomationTableA->MethodSetsCount;
@@ -2136,8 +2151,14 @@ KspCountEventSets(
     if (!AutomationTableB)
         return AutomationTableA->EventSetsCount;
 
-    /* sanity check */
-    ASSERT(AutomationTableA->EventItemSize == AutomationTableB->EventItemSize);
+    DPRINT("AutomationTableA EventItemSize %lu EventSetsCount %lu\n", AutomationTableA->EventItemSize, AutomationTableA->EventSetsCount);
+    DPRINT("AutomationTableB EventItemSize %lu EventSetsCount %lu\n", AutomationTableB->EventItemSize, AutomationTableB->EventSetsCount);
+
+    if (AutomationTableA->EventItemSize && AutomationTableB->EventItemSize)
+    {
+        /* sanity check */
+        ASSERT(AutomationTableA->EventItemSize == AutomationTableB->EventItemSize);
+    }
 
     /* now iterate all Event sets and compare their guids */
     Count = AutomationTableA->EventSetsCount;
@@ -2180,6 +2201,8 @@ KspCountPropertySets(
         return AutomationTableA->PropertySetsCount;
 
     /* sanity check */
+    DPRINT("AutomationTableA PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableA->PropertyItemSize, AutomationTableA->PropertySetsCount);
+    DPRINT("AutomationTableB PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableB->PropertyItemSize, AutomationTableB->PropertySetsCount);
     ASSERT(AutomationTableA->PropertyItemSize == AutomationTableB->PropertyItemSize);
 
     /* now iterate all property sets and compare their guids */
@@ -2219,18 +2242,18 @@ KspCopyMethodSets(
     if (!AutomationTableA)
     {
         /* copy of property set */
-        RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableB->MethodSets, Table->MethodItemSize * AutomationTableB->MethodSetsCount);
+        RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableB->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableB->MethodSetsCount);
         return STATUS_SUCCESS;
     }
     else if (!AutomationTableB)
     {
         /* copy of property set */
-        RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, Table->MethodItemSize * AutomationTableA->MethodSetsCount);
+        RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableA->MethodSetsCount);
         return STATUS_SUCCESS;
     }
 
     /* first copy all property items from dominant table */
-    RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, Table->MethodItemSize * AutomationTableA->MethodSetsCount);
+    RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableA->MethodSetsCount);
     /* set counter */
     Count = AutomationTableA->MethodSetsCount;
 
@@ -2253,7 +2276,7 @@ KspCopyMethodSets(
         if (!bFound)
         {
             /* copy new property item set */
-            RtlMoveMemory((PVOID)&Table->MethodSets[Count], &AutomationTableB->MethodSets[Index], Table->MethodItemSize);
+            RtlMoveMemory((PVOID)&Table->MethodSets[Count], &AutomationTableB->MethodSets[Index], sizeof(KSMETHOD_SET));
             Count++;
         }
     }
@@ -2274,18 +2297,18 @@ KspCopyPropertySets(
     if (!AutomationTableA)
     {
         /* copy of property set */
-        RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableB->PropertySets, Table->PropertyItemSize * AutomationTableB->PropertySetsCount);
+        RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableB->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableB->PropertySetsCount);
         return STATUS_SUCCESS;
     }
     else if (!AutomationTableB)
     {
         /* copy of property set */
-        RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, Table->PropertyItemSize * AutomationTableA->PropertySetsCount);
+        RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableA->PropertySetsCount);
         return STATUS_SUCCESS;
     }
 
     /* first copy all property items from dominant table */
-    RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, Table->PropertyItemSize * AutomationTableA->PropertySetsCount);
+    RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableA->PropertySetsCount);
     /* set counter */
     Count = AutomationTableA->PropertySetsCount;
 
@@ -2308,7 +2331,7 @@ KspCopyPropertySets(
         if (!bFound)
         {
             /* copy new property item set */
-            RtlMoveMemory((PVOID)&Table->PropertySets[Count], &AutomationTableB->PropertySets[Index], Table->PropertyItemSize);
+            RtlMoveMemory((PVOID)&Table->PropertySets[Count], &AutomationTableB->PropertySets[Index], sizeof(KSPROPERTY_SET));
             Count++;
         }
     }
@@ -2328,18 +2351,18 @@ KspCopyEventSets(
     if (!AutomationTableA)
     {
         /* copy of Event set */
-        RtlMoveMemory((PVOID)Table->EventSets, AutomationTableB->EventSets, Table->EventItemSize * AutomationTableB->EventSetsCount);
+        RtlMoveMemory((PVOID)Table->EventSets, AutomationTableB->EventSets, sizeof(KSEVENT_SET) * AutomationTableB->EventSetsCount);
         return STATUS_SUCCESS;
     }
     else if (!AutomationTableB)
     {
         /* copy of Event set */
-        RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, Table->EventItemSize * AutomationTableA->EventSetsCount);
+        RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, sizeof(KSEVENT_SET) * AutomationTableA->EventSetsCount);
         return STATUS_SUCCESS;
     }
 
     /* first copy all Event items from dominant table */
-    RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, Table->EventItemSize * AutomationTableA->EventSetsCount);
+    RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, sizeof(KSEVENT_SET) * AutomationTableA->EventSetsCount);
     /* set counter */
     Count = AutomationTableA->EventSetsCount;
 
@@ -2362,7 +2385,7 @@ KspCopyEventSets(
         if (!bFound)
         {
             /* copy new Event item set */
-            RtlMoveMemory((PVOID)&Table->EventSets[Count], &AutomationTableB->EventSets[Index], Table->EventItemSize);
+            RtlMoveMemory((PVOID)&Table->EventSets[Count], &AutomationTableB->EventSets[Index], sizeof(KSEVENT_SET));
             Count++;
         }
     }
@@ -2426,7 +2449,7 @@ KsMergeAutomationTables(
         }
 
         /* now allocate the property sets */
-        Table->PropertySets = AllocateItem(NonPagedPool, Table->PropertyItemSize * Table->PropertySetsCount);
+        Table->PropertySets = AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * Table->PropertySetsCount);
 
         if (!Table->PropertySets)
         {
@@ -2469,7 +2492,7 @@ KsMergeAutomationTables(
         }
 
         /* now allocate the property sets */
-        Table->MethodSets = AllocateItem(NonPagedPool, Table->MethodItemSize * Table->MethodSetsCount);
+        Table->MethodSets = AllocateItem(NonPagedPool, sizeof(KSMETHOD_SET) * Table->MethodSetsCount);
 
         if (!Table->MethodSets)
         {
@@ -2512,7 +2535,7 @@ KsMergeAutomationTables(
         }
 
         /* now allocate the property sets */
-        Table->EventSets = AllocateItem(NonPagedPool, Table->EventItemSize * Table->EventSetsCount);
+        Table->EventSets = AllocateItem(NonPagedPool, sizeof(KSEVENT_SET) * Table->EventSetsCount);
 
         if (!Table->EventSets)
         {
@@ -2683,8 +2706,26 @@ KsRegisterAggregatedClientUnknown(
     IN PVOID  Object,
     IN PUNKNOWN  ClientUnknown)
 {
-    UNIMPLEMENTED
-    return NULL;
+    PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
+
+    /* sanity check */
+    ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || 
+           BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
+
+    if (BasicHeader->ClientAggregate)
+    {
+        /* release existing aggregate */
+        BasicHeader->ClientAggregate->lpVtbl->Release(BasicHeader->ClientAggregate);
+    }
+
+    /* increment reference count */
+    ClientUnknown->lpVtbl->AddRef(ClientUnknown);
+
+    /* store client aggregate */
+    BasicHeader->ClientAggregate = ClientUnknown;
+
+    /* return objects outer unknown */
+    return BasicHeader->OuterUnknown;
 }
 
 /*
index 1b7eec9..87f7a2b 100644 (file)
@@ -41,7 +41,7 @@ KsAllocateObjectBag(
         return STATUS_INSUFFICIENT_RESOURCES;
 
     /* get device interface */
-    KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
+    KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
 
     /* initialize object bag */
     return KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Bag, NULL);
@@ -89,6 +89,8 @@ KsAddItemToObjectBag(
     PKSIOBJECT_BAG Bag;
     PKSIOBJECT_BAG_ENTRY BagEntry;
 
+    DPRINT("KsAddItemToObjectBag\n");
+
     /* get real object bag */
     Bag = (PKSIOBJECT_BAG)ObjectBag;
 
@@ -363,6 +365,8 @@ _KsEdit(
     PVOID Item;
     NTSTATUS Status;
 
+    DPRINT("_KsEdit\n");
+
     /* get real object bag */
     Bag = (PKSIOBJECT_BAG)ObjectBag;
 
index 3961193..05064be 100644 (file)
@@ -21,20 +21,235 @@ typedef struct
     PFNKSSETTIMER SetTimer;
     PFNKSCANCELTIMER CancelTimer;
     PFNKSCORRELATEDTIME CorrelatedTime;
-    KSRESOLUTION* Resolution;
+    LONGLONG Granularity;
+    LONGLONG Error;
     ULONG Flags;
 
 }KSIDEFAULTCLOCK, *PKSIDEFAULTCLOCK;
 
 typedef struct
 {
-    IKsClock *lpVtbl;
     LONG ref;
     PKSCLOCK_CREATE ClockCreate;
     PKSIDEFAULTCLOCK DefaultClock;
     PKSIOBJECT_HEADER ObjectHeader;
 }KSICLOCK, *PKSICLOCK;
 
+NTSTATUS NTAPI ClockPropertyTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyCorrelatedTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyCorrelatedPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyResolution(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyFunctionTable(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+
+DEFINE_KSPROPERTY_CLOCKSET(ClockPropertyTable, ClockPropertyTime, ClockPropertyPhysicalTime, ClockPropertyCorrelatedTime, ClockPropertyCorrelatedPhysicalTime, ClockPropertyResolution, ClockPropertyState, ClockPropertyFunctionTable);
+
+KSPROPERTY_SET ClockPropertySet[] =
+{
+    {
+        &KSPROPSETID_Clock,
+        sizeof(ClockPropertyTable) / sizeof(KSPROPERTY_ITEM),
+        (const KSPROPERTY_ITEM*)&ClockPropertyTable,
+        0,
+        NULL
+    }
+};
+
+LONGLONG
+FASTCALL
+ClockGetPhysicalTime(
+    IN PFILE_OBJECT FileObject)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+LONGLONG
+FASTCALL
+ClockGetCorrelatedTime(
+    IN PFILE_OBJECT FileObject,
+    OUT PLONGLONG SystemTime)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+LONGLONG
+FASTCALL
+ClockGetTime(
+    IN PFILE_OBJECT FileObject)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+LONGLONG
+FASTCALL
+ClockGetCorrelatedPhysicalTime(
+    IN PFILE_OBJECT FileObject,
+    OUT PLONGLONG SystemTime)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PLONGLONG Time = (PLONGLONG)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyTime\n");
+
+    *Time = ClockGetTime(IoStack->FileObject);
+
+    Irp->IoStatus.Information = sizeof(LONGLONG);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyPhysicalTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PLONGLONG Time = (PLONGLONG)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyPhysicalTime\n");
+
+    *Time = ClockGetPhysicalTime(IoStack->FileObject);
+
+    Irp->IoStatus.Information = sizeof(LONGLONG);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyCorrelatedTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyCorrelatedTime\n");
+
+    Time->Time = ClockGetCorrelatedTime(IoStack->FileObject, &Time->SystemTime);
+
+    Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyCorrelatedPhysicalTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyCorrelatedPhysicalTime\n");
+
+    Time->Time = ClockGetCorrelatedPhysicalTime(IoStack->FileObject, &Time->SystemTime);
+
+    Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyResolution(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSICLOCK Clock;
+    PKSIOBJECT_HEADER ObjectHeader;
+    PIO_STACK_LOCATION IoStack;
+    PKSRESOLUTION Resolution = (PKSRESOLUTION)Data;
+
+    DPRINT("ClockPropertyResolution\n");
+
+    /* get stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* sanity check */
+    ASSERT(ObjectHeader);
+
+    /* locate ks pin implemention from KSPIN offset */
+    Clock = (PKSICLOCK)ObjectHeader->ObjectType;
+
+    Resolution->Error = Clock->DefaultClock->Error;
+    Resolution->Granularity = Clock->DefaultClock->Granularity;
+
+    Irp->IoStatus.Information = sizeof(KSRESOLUTION);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyState(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSICLOCK Clock;
+    PKSIOBJECT_HEADER ObjectHeader;
+    PKSSTATE State = (PKSSTATE)Data;
+    PIO_STACK_LOCATION IoStack;
+
+    DPRINT("ClockPropertyState\n");
+
+    /* get stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* sanity check */
+    ASSERT(ObjectHeader);
+
+    /* locate ks pin implemention from KSPIN offset */
+    Clock = (PKSICLOCK)ObjectHeader->ObjectType;
+
+    *State = Clock->DefaultClock->State;
+    Irp->IoStatus.Information = sizeof(KSSTATE);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyFunctionTable(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSCLOCK_FUNCTIONTABLE Table = (PKSCLOCK_FUNCTIONTABLE)Data;
+
+    DPRINT("ClockPropertyFunctionTable\n");
+
+    Table->GetCorrelatedPhysicalTime = ClockGetCorrelatedPhysicalTime;
+    Table->GetCorrelatedTime = ClockGetCorrelatedTime;
+    Table->GetPhysicalTime = ClockGetPhysicalTime;
+    Table->GetTime = ClockGetTime;
+
+    return STATUS_SUCCESS;
+}
+
 
 /*
     @implemented
@@ -96,12 +311,37 @@ IKsClock_DispatchDeviceIoControl(
     IN PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp)
 {
-    UNIMPLEMENTED
+    PIO_STACK_LOCATION IoStack;
+    UNICODE_STRING GuidString;
+    PKSPROPERTY Property;
+    NTSTATUS Status;
+
+    DPRINT("IKsClock_DispatchDeviceIoControl\n");
 
-    Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+    /* get current io stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* FIXME support events */
+    ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
+
+    /* sanity check */
+    ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSPROPERTY));
+
+    /* call property handler */
+    Status = KsPropertyHandler(Irp, 1, ClockPropertySet);
+
+    /* get property from input buffer */
+    Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+    RtlStringFromGUID(&Property->Set, &GuidString);
+    DPRINT("IKsClock_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information);
+    RtlFreeUnicodeString(&GuidString);
+
+
+    Irp->IoStatus.Status = STATUS_SUCCESS;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-    return STATUS_NOT_IMPLEMENTED;
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
@@ -112,14 +352,12 @@ IKsClock_DispatchClose(
 {
     UNIMPLEMENTED
 
-    Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+    Irp->IoStatus.Status = STATUS_SUCCESS;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-    return STATUS_NOT_IMPLEMENTED;
+    return STATUS_SUCCESS;
 }
 
-
-
 static KSDISPATCH_TABLE DispatchTable =
 {
     IKsClock_DispatchDeviceIoControl,
@@ -147,7 +385,6 @@ KsCreateDefaultClock(
     NTSTATUS Status;
     PKSCLOCK_CREATE ClockCreate;
     PKSICLOCK Clock;
-    PKSOBJECT_CREATE_ITEM CreateItem;
 
     Status = KsValidateClockCreateRequest(Irp, &ClockCreate);
     if (!NT_SUCCESS(Status))
@@ -171,7 +408,7 @@ KsCreateDefaultClock(
 
     /* initialize clock */
     /* FIXME IKsClock */
-    Clock->ObjectHeader->Unknown = (PUNKNOWN)&Clock->lpVtbl;
+    Clock->ObjectHeader->ObjectType = (PVOID)Clock;
     Clock->ref = 1;
     Clock->ClockCreate = ClockCreate;
     Clock->DefaultClock = (PKSIDEFAULTCLOCK)DefaultClock;
@@ -179,9 +416,6 @@ KsCreateDefaultClock(
     /* increment reference count */
     InterlockedIncrement(&Clock->DefaultClock->ReferenceCount);
 
-    /* get create item */
-    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
-
     return Status;
 }
 
@@ -230,9 +464,21 @@ KsAllocateDefaultClockEx(
     Clock->SetTimer = SetTimer;
     Clock->CancelTimer = CancelTimer;
     Clock->CorrelatedTime = CorrelatedTime;
-    Clock->Resolution = (PKSRESOLUTION)Resolution;
     Clock->Flags = Flags;
 
+    if (Resolution)
+    {
+        if (SetTimer)
+        {
+            Clock->Error = Resolution->Error;
+        }
+
+        if (CorrelatedTime)
+        {
+            Clock->Granularity = Resolution->Granularity;
+        }
+    }
+
     *DefaultClock = (PKSDEFAULTCLOCK)Clock;
     return STATUS_SUCCESS;
 }
index 7c9b822..bcc55cc 100644 (file)
@@ -23,6 +23,7 @@ KSPIN_MEDIUM StandardPinMedium =
     0
 };
 
+const GUID KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT = {0xf4aeb342, 0x0329, 0x4fdd, {0xa8, 0xfd, 0x4a, 0xff, 0x49, 0x26, 0xc9, 0x78}};
 
 /*
     @implemented
@@ -53,16 +54,12 @@ KsCreatePin(
                                ConnectionHandle);
 }
 
-/*
-    @unimplemented
-*/
-KSDDKAPI
 NTSTATUS
-NTAPI
-KsValidateConnectRequest(
-    IN  PIRP Irp,
-    IN  ULONG DescriptorsCount,
-    IN  KSPIN_DESCRIPTOR* Descriptor,
+KspValidateConnectRequest(
+    IN PIRP Irp,
+    IN ULONG DescriptorsCount,
+    IN PVOID Descriptors,
+    IN ULONG DescriptorSize,
     OUT PKSPIN_CONNECT* Connect)
 {
     PKSPIN_CONNECT ConnectDetails;
@@ -73,6 +70,7 @@ KsValidateConnectRequest(
     ULONG Index;
     ULONG Count;
     BOOLEAN Found;
+    PKSPIN_DESCRIPTOR Descriptor;
 
     /* did the caller miss the connect parameter */
     if (!Connect)
@@ -95,12 +93,24 @@ KsValidateConnectRequest(
     if (ConnectDetails->PinId >= DescriptorsCount)
         return STATUS_INVALID_PARAMETER;
 
+    if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR))
+    {
+        /* standard pin descriptor */
+        Descriptor = (PKSPIN_DESCRIPTOR)((ULONG_PTR)Descriptors + sizeof(KSPIN_DESCRIPTOR) * ConnectDetails->PinId);
+    }
+    else
+    {
+        /* extended / variable pin descriptor */
+        Descriptor = &((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + DescriptorSize * ConnectDetails->PinId))->PinDescriptor;
+    }
+
+
     /* does the pin have interface details filled in */
-    if (Descriptor[ConnectDetails->PinId].InterfacesCount && Descriptor[ConnectDetails->PinId].Interfaces)
+    if (Descriptor->InterfacesCount && Descriptor->Interfaces)
     {
         /* use provided pin interface count */
-        Count = Descriptor[ConnectDetails->PinId].InterfacesCount;
-        Interface = (PKSPIN_INTERFACE)Descriptor[ConnectDetails->PinId].Interfaces;
+        Count = Descriptor->InterfacesCount;
+        Interface = (PKSPIN_INTERFACE)Descriptor->Interfaces;
     }
     else
     {
@@ -114,6 +124,13 @@ KsValidateConnectRequest(
     Index = 0;
     do
     {
+        UNICODE_STRING GuidString, GuidString2;
+        RtlStringFromGUID(&Interface[Index].Set, &GuidString);
+        RtlStringFromGUID(&ConnectDetails->Interface.Set, &GuidString2);
+
+        DPRINT("Driver Interface %S Id %u\n", GuidString.Buffer, Interface[Index].Id);
+        DPRINT("Connect Interface %S Id %u\n", GuidString2.Buffer, ConnectDetails->Interface.Id);
+
         if (IsEqualGUIDAligned(&Interface[Index].Set, &ConnectDetails->Interface.Set) &&
                                Interface[Index].Id == ConnectDetails->Interface.Id)
         {
@@ -132,11 +149,11 @@ KsValidateConnectRequest(
     }
 
     /* does the pin have medium details filled in */
-    if (Descriptor[ConnectDetails->PinId].MediumsCount && Descriptor[ConnectDetails->PinId].Mediums)
+    if (Descriptor->MediumsCount && Descriptor->Mediums)
     {
         /* use provided pin interface count */
-        Count = Descriptor[ConnectDetails->PinId].MediumsCount;
-        Medium = (PKSPIN_MEDIUM)Descriptor[ConnectDetails->PinId].Mediums;
+        Count = Descriptor->MediumsCount;
+        Medium = (PKSPIN_MEDIUM)Descriptor->Mediums;
     }
     else
     {
@@ -150,6 +167,14 @@ KsValidateConnectRequest(
     Index = 0;
     do
     {
+        UNICODE_STRING GuidString, GuidString2;
+        RtlStringFromGUID(&Medium[Index].Set, &GuidString);
+        RtlStringFromGUID(&ConnectDetails->Medium.Set, &GuidString2);
+
+        DPRINT("Driver Medium %S Id %u\n", GuidString.Buffer, Medium[Index].Id);
+        DPRINT("Connect Medium %S Id %u\n", GuidString2.Buffer, ConnectDetails->Medium.Id);
+
+
         if (IsEqualGUIDAligned(&Medium[Index].Set, &ConnectDetails->Medium.Set) &&
                                Medium[Index].Id == ConnectDetails->Medium.Id)
         {
@@ -157,6 +182,9 @@ KsValidateConnectRequest(
             Found = TRUE;
             break;
         }
+
+
+
         /* iterate to next medium */
         Index++;
     }while(Index < Count);
@@ -174,6 +202,20 @@ KsValidateConnectRequest(
     return STATUS_SUCCESS;
 }
 
+/*
+    @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsValidateConnectRequest(
+    IN  PIRP Irp,
+    IN  ULONG DescriptorsCount,
+    IN  KSPIN_DESCRIPTOR* Descriptor,
+    OUT PKSPIN_CONNECT* Connect)
+{
+    return KspValidateConnectRequest(Irp, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR), Connect);
+}
 
 NTSTATUS
 KspReadMediaCategory(
@@ -265,18 +307,16 @@ KspReadMediaCategory(
     return Status;
 }
 
-/*
-    @implemented
-*/
 KSDDKAPI
 NTSTATUS
 NTAPI
-KsPinPropertyHandler(
+KspPinPropertyHandler(
     IN  PIRP Irp,
     IN  PKSPROPERTY Property,
     IN  OUT PVOID Data,
     IN  ULONG DescriptorsCount,
-    IN  const KSPIN_DESCRIPTOR* Descriptor)
+    IN  const KSPIN_DESCRIPTOR* Descriptors,
+    IN  ULONG DescriptorSize)
 {
     KSP_PIN * Pin;
     KSMULTIPLE_ITEM * Item;
@@ -286,12 +326,38 @@ KsPinPropertyHandler(
     PKSDATARANGE_AUDIO *WaveFormatOut;
     PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn;
     PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+    const KSPIN_DESCRIPTOR *Descriptor;
     NTSTATUS Status = STATUS_NOT_SUPPORTED;
+    ULONG Count;
+    const PKSDATARANGE* DataRanges;
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
     Buffer = Irp->UserBuffer;
 
-    DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id);
+    //DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id);
+
+    /* convert to PKSP_PIN */
+    Pin = (KSP_PIN*)Property;
+
+    if (Property->Id != KSPROPERTY_PIN_CTYPES)
+    {
+        if (Pin->PinId >= DescriptorsCount)
+        {
+            /* invalid parameter */
+            return STATUS_INVALID_PARAMETER;
+        }
+    }
+
+    if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR))
+    {
+        /* it is simple pin descriptor */
+        Descriptor = &Descriptors[Pin->PinId];
+    }
+    else
+    {
+        /* get offset to pin descriptor */
+        Descriptor = &(((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + Pin->PinId * DescriptorSize))->PinDescriptor);
+    }
 
     switch(Property->Id)
     {
@@ -301,13 +367,7 @@ KsPinPropertyHandler(
             Status = STATUS_SUCCESS;
             break;
         case KSPROPERTY_PIN_DATAFLOW:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
+
             Size = sizeof(KSPIN_DATAFLOW);
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
             {
@@ -316,23 +376,31 @@ KsPinPropertyHandler(
                 break;
             }
 
-            *((KSPIN_DATAFLOW*)Buffer) = Descriptor[Pin->PinId].DataFlow;
+            *((KSPIN_DATAFLOW*)Buffer) = Descriptor->DataFlow;
             Irp->IoStatus.Information = sizeof(KSPIN_DATAFLOW);
             Status = STATUS_SUCCESS;
             break;
 
         case KSPROPERTY_PIN_DATARANGES:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
+        case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
+
+            Size = sizeof(KSMULTIPLE_ITEM);
+            DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property->Id, Pin->PinId, Descriptor->DataRangesCount, Descriptor->ConstrainedDataRangesCount);
+
+            if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor->ConstrainedDataRangesCount == 0)
             {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
+                DataRanges = Descriptor->DataRanges;
+                Count = Descriptor->DataRangesCount;
             }
-            Size = sizeof(KSMULTIPLE_ITEM);
-            for (Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++)
+            else
             {
-                Size += Descriptor[Pin->PinId].DataRanges[Index]->FormatSize;
+                DataRanges = Descriptor->ConstrainedDataRanges;
+                Count = Descriptor->ConstrainedDataRangesCount;
+            }
+
+            for (Index = 0; Index < Count; Index++)
+            {
+                Size += ((DataRanges[Index]->FormatSize + 0x7) & ~0x7);
             }
 
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
@@ -354,16 +422,9 @@ KsPinPropertyHandler(
                 break;
             }
 
-            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSMULTIPLE_ITEM))
-            {
-                /* buffer too small */
-                Status = STATUS_BUFFER_TOO_SMALL;
-                break;
-            }
-
             /* store descriptor size */
             Item->Size = Size;
-            Item->Count = Descriptor[Pin->PinId].DataRangesCount;
+            Item->Count = Count;
 
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSMULTIPLE_ITEM))
             {
@@ -374,28 +435,40 @@ KsPinPropertyHandler(
 
             /* now copy all dataranges */
             Data = (PUCHAR)(Item +1);
-            for (Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++)
+
+            /* alignment assert */
+            ASSERT(((ULONG_PTR)Data & 0x7) == 0);
+
+            for (Index = 0; Index < Count; Index++)
             {
-                RtlMoveMemory(Data, Descriptor[Pin->PinId].DataRanges[Index], Descriptor[Pin->PinId].DataRanges[Index]->FormatSize);
-                Data = ((PUCHAR)Data + Descriptor[Pin->PinId].DataRanges[Index]->FormatSize);
+                UNICODE_STRING GuidString;
+                /* convert the guid to string */
+                RtlStringFromGUID(&DataRanges[Index]->MajorFormat, &GuidString);
+                DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer);
+                RtlStringFromGUID(&DataRanges[Index]->SubFormat, &GuidString);
+                DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer);
+                RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString);
+                DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer);
+                RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString);
+                DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index,
+                       DataRanges[Index]->FormatSize, DataRanges[Index]->Flags, DataRanges[Index]->SampleSize, DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT));
+
+                RtlMoveMemory(Data, DataRanges[Index], DataRanges[Index]->FormatSize);
+                Data = ((PUCHAR)Data + DataRanges[Index]->FormatSize);
+                /* alignment assert */
+                ASSERT(((ULONG_PTR)Data & 0x7) == 0);
+                Data = (PVOID)(((ULONG_PTR)Data + 0x7) & ~0x7);
             }
 
             Status = STATUS_SUCCESS;
             Irp->IoStatus.Information = Size;
             break;
         case KSPROPERTY_PIN_INTERFACES:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
 
-            if (Descriptor[Pin->PinId].Interfaces)
+            if (Descriptor->Interfaces)
             {
                 /* use mediums provided by driver */
-                return KsHandleSizedListQuery(Irp, Descriptor[Pin->PinId].InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor[Pin->PinId].Interfaces);
+                return KsHandleSizedListQuery(Irp, Descriptor->InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor->Interfaces);
             }
             else
             {
@@ -405,18 +478,11 @@ KsPinPropertyHandler(
             break;
 
         case KSPROPERTY_PIN_MEDIUMS:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
 
-            if (Descriptor[Pin->PinId].MediumsCount)
+            if (Descriptor->MediumsCount)
             {
                 /* use mediums provided by driver */
-                return KsHandleSizedListQuery(Irp, Descriptor[Pin->PinId].MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor[Pin->PinId].Mediums);
+                return KsHandleSizedListQuery(Irp, Descriptor->MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor->Mediums);
             }
             else
             {
@@ -426,13 +492,6 @@ KsPinPropertyHandler(
             break;
 
         case KSPROPERTY_PIN_COMMUNICATION:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
 
             Size = sizeof(KSPIN_COMMUNICATION);
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
@@ -442,19 +501,13 @@ KsPinPropertyHandler(
                 break;
             }
 
-            *((KSPIN_COMMUNICATION*)Buffer) = Descriptor[Pin->PinId].Communication;
+            *((KSPIN_COMMUNICATION*)Buffer) = Descriptor->Communication;
+
             Status = STATUS_SUCCESS;
             Irp->IoStatus.Information = Size;
             break;
 
         case KSPROPERTY_PIN_CATEGORY:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
 
             Size = sizeof(GUID);
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
@@ -463,9 +516,9 @@ KsPinPropertyHandler(
                 Status = STATUS_BUFFER_TOO_SMALL;
                 break;
             }
-            if (Descriptor[Pin->PinId].Category)
+            if (Descriptor->Category)
             {
-                RtlMoveMemory(Buffer, Descriptor[Pin->PinId].Category, sizeof(GUID));
+                RtlMoveMemory(Buffer, Descriptor->Category, sizeof(GUID));
             }
 
             Status = STATUS_SUCCESS;
@@ -473,29 +526,20 @@ KsPinPropertyHandler(
             break;
 
         case KSPROPERTY_PIN_NAME:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
-
-            if (!Descriptor[Pin->PinId].Name)
+            if (!Descriptor->Name)
             {
                 Irp->IoStatus.Information = 0;
                 Status = STATUS_SUCCESS;
                 break;
             }
 
-            Status = KspReadMediaCategory((LPGUID)Descriptor[Pin->PinId].Name, &KeyInfo);
+            Status = KspReadMediaCategory((LPGUID)Descriptor->Name, &KeyInfo);
             if (!NT_SUCCESS(Status))
             {
                 Irp->IoStatus.Information = 0;
                 break;
             }
 
-
             Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);
 
             if (KeyInfo->DataLength + sizeof(WCHAR) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
@@ -510,13 +554,6 @@ KsPinPropertyHandler(
             ExFreePool(KeyInfo);
             break;
         case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
-            Pin = (KSP_PIN*)Property;
-            if (Pin->PinId >= DescriptorsCount)
-            {
-                Status = STATUS_INVALID_PARAMETER;
-                Irp->IoStatus.Information = 0;
-                break;
-            }
             Size = sizeof(KSDATAFORMAT);
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
             {
@@ -533,14 +570,14 @@ KsPinPropertyHandler(
             }
 
             WaveFormatIn = (PKSDATAFORMAT_WAVEFORMATEX)Buffer;
-            if (!Descriptor[Pin->PinId].DataRanges || !Descriptor[Pin->PinId].DataRangesCount)
+            if (!Descriptor->DataRanges || !Descriptor->DataRangesCount)
             {
                 Status = STATUS_UNSUCCESSFUL;
                 Irp->IoStatus.Information = 0;
                 break;
             }
-            WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor[Pin->PinId].DataRanges;
-            for(Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++)
+            WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor->DataRanges;
+            for(Index = 0; Index < Descriptor->DataRangesCount; Index++)
             {
                 if (WaveFormatOut[Index]->DataRange.FormatSize != sizeof(KSDATARANGE_AUDIO))
                 {
@@ -577,6 +614,22 @@ KsPinPropertyHandler(
     return Status;
 }
 
+/*
+    @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsPinPropertyHandler(
+    IN  PIRP Irp,
+    IN  PKSPROPERTY Property,
+    IN  OUT PVOID Data,
+    IN  ULONG DescriptorsCount,
+    IN  const KSPIN_DESCRIPTOR* Descriptor)
+{
+    return KspPinPropertyHandler(Irp, Property, Data, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR));
+}
+
 /*
     @unimplemented
 */
index 345689f..432548c 100644 (file)
@@ -16,15 +16,29 @@ IKsDevice_fnQueryInterface(
     REFIID refiid,
     PVOID* Output)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    NTSTATUS Status;
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
     {
-        *Output = &This->lpVtblIKsDevice;
+        *Output = &This->BasicHeader.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
 
+    if (This->BasicHeader.ClientAggregate)
+    {
+         /* using client aggregate */
+         Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output);
+
+         if (NT_SUCCESS(Status))
+         {
+             /* client aggregate supports interface */
+             return Status;
+         }
+    }
+
+    DPRINT("IKsDevice_fnQueryInterface no interface\n");
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -33,7 +47,7 @@ NTAPI
 IKsDevice_fnAddRef(
     IN IKsDevice * iface)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     return InterlockedIncrement(&This->ref);
 }
@@ -43,7 +57,7 @@ NTAPI
 IKsDevice_fnRelease(
     IN IKsDevice * iface)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     InterlockedDecrement(&This->ref);
 
@@ -57,7 +71,7 @@ NTAPI
 IKsDevice_fnGetStruct(
     IN IKsDevice * iface)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     return &This->KsDevice;
 }
@@ -69,7 +83,7 @@ IKsDevice_fnInitializeObjectBag(
     IN PKSIOBJECT_BAG Bag,
     IN PRKMUTEX Mutex)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     if (!Mutex)
     {
@@ -93,7 +107,7 @@ NTAPI
 IKsDevice_fnAcquireDevice(
     IN IKsDevice * iface)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     return KeWaitForSingleObject(&This->DeviceMutex, Executive, KernelMode, FALSE, NULL);
 }
@@ -103,7 +117,7 @@ NTAPI
 IKsDevice_fnReleaseDevice(
     IN IKsDevice * iface)
 {
-    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     return KeReleaseMutex(&This->DeviceMutex, FALSE);
 }
@@ -112,14 +126,17 @@ NTSTATUS
 NTAPI
 IKsDevice_fnGetAdapterObject(
     IN IKsDevice * iface,
-    IN PADAPTER_OBJECT Object,
-    IN PULONG Unknown1,
-    IN PULONG Unknown2)
+    IN PADAPTER_OBJECT Object,
+    IN PULONG MaxMappingsByteCount,
+    IN PULONG MappingTableStride)
 {
-    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    *Object = This->AdapterObject;
+    *MaxMappingsByteCount = This->MaxMappingsByteCount;
+    *MappingTableStride = This->MappingTableStride;
+
+    return STATUS_SUCCESS;
 
 }
 
@@ -130,7 +147,7 @@ IKsDevice_fnAddPowerEntry(
     IN struct KSPOWER_ENTRY * Entry,
     IN IKsPowerNotify* Notify)
 {
-    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
@@ -142,7 +159,7 @@ IKsDevice_fnRemovePowerEntry(
     IN IKsDevice * iface,
     IN struct KSPOWER_ENTRY * Entry)
 {
-    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
@@ -158,7 +175,7 @@ IKsDevice_fnPinStateChange(
     IN KSSTATE OldState,
     IN KSSTATE NewState)
 {
-    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
@@ -169,15 +186,24 @@ NTSTATUS
 NTAPI
 IKsDevice_fnArbitrateAdapterChannel(
     IN IKsDevice * iface,
-    IN ULONG ControlCode,
-    IN IO_ALLOCATION_ACTION Action,
+    IN ULONG NumberOfMapRegisters,
+    IN PDRIVER_CONTROL ExecutionRoutine,
     IN PVOID Context)
 {
-    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
+    NTSTATUS Status;
 
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    DPRINT("IKsDevice_fnArbitrateAdapterChannel NumberOfMapRegisters %lu ExecutionRoutine %p Context %p Irql %lu\n", NumberOfMapRegisters, ExecutionRoutine, Context, KeGetCurrentIrql());
+
+    /* sanity check */
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    ASSERT(This->AdapterObject);
 
+    /* allocate adapter channel */
+    Status = IoAllocateAdapterChannel(This->AdapterObject, This->KsDevice.FunctionalDeviceObject, NumberOfMapRegisters, ExecutionRoutine, Context);
+
+    /* done */
+    return Status;
 }
 
 NTSTATUS
@@ -186,7 +212,7 @@ IKsDevice_fnCheckIoCapability(
     IN IKsDevice * iface,
     IN ULONG Unknown)
 {
-    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
+    //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
 
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
@@ -492,7 +518,7 @@ IKsDevice_Pnp(
         }
         case IRP_MN_QUERY_INTERFACE:
         {
-            Status = STATUS_SUCCESS;
+            Status = STATUS_UNSUCCESSFUL;
             /* check for pnp notification support */
             if (Dispatch)
             {
@@ -508,6 +534,7 @@ IKsDevice_Pnp(
             if (NT_SUCCESS(Status))
             {
                 /* driver supports a private interface */
+                DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n");
                 Irp->IoStatus.Status = Status;
                 IoCompleteRequest(Irp, IO_NO_INCREMENT);
                 return Status;
@@ -517,7 +544,6 @@ IKsDevice_Pnp(
             Status = KspForwardIrpSynchronous(DeviceObject, Irp);
 
             DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status);
-
             Irp->IoStatus.Status = Status;
             IoCompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
@@ -557,8 +583,12 @@ IKsDevice_Pnp(
        }
        default:
           DPRINT1("unhandled function %u\n", IoStack->MinorFunction);
+          /* pass the irp down the driver stack */
+          Status = KspForwardIrpSynchronous(DeviceObject, Irp);
+
+          Irp->IoStatus.Status = Status;
           IoCompleteRequest(Irp, IO_NO_INCREMENT);
-          return STATUS_NOT_SUPPORTED;
+          return Status;
     }
 }
 
@@ -601,7 +631,7 @@ IKsDevice_Create(
     DeviceHeader = DeviceExtension->DeviceHeader;
 
     /* acquire list lock */
-    IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
+    IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
 
     /* sanity check */
     ASSERT(IoStack->FileObject);
@@ -640,7 +670,7 @@ IKsDevice_Create(
     }
 
     /* acquire list lock */
-    IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
+    IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
 
     if (Status != STATUS_PENDING)
     {
@@ -686,6 +716,23 @@ KsInitializeDevice(
 
     DPRINT("DeviceHeader %p\n", DeviceExtension->DeviceHeader);
 
+    if (Descriptor && Descriptor->Dispatch)
+    {
+        DPRINT("Descriptor Add %p\n", Descriptor->Dispatch->Add);
+        DPRINT("Descriptor Start %p\n", Descriptor->Dispatch->Start);
+        DPRINT("Descriptor PostStart %p\n", Descriptor->Dispatch->PostStart);
+        DPRINT("Descriptor QueryStop %p\n", Descriptor->Dispatch->QueryStop);
+        DPRINT("Descriptor CancelStop %p\n", Descriptor->Dispatch->CancelStop);
+        DPRINT("Descriptor Stop %p\n", Descriptor->Dispatch->Stop);
+        DPRINT("Descriptor QueryRemove %p\n", Descriptor->Dispatch->QueryRemove);
+        DPRINT("Descriptor CancelRemove %p\n", Descriptor->Dispatch->CancelRemove);
+        DPRINT("Descriptor Remove %p\n", Descriptor->Dispatch->Remove);
+        DPRINT("Descriptor QueryCapabilities %p\n", Descriptor->Dispatch->QueryCapabilities);
+        DPRINT("Descriptor SurpriseRemoval %p\n", Descriptor->Dispatch->SurpriseRemoval);
+        DPRINT("Descriptor QueryPower %p\n", Descriptor->Dispatch->QueryPower);
+        DPRINT("Descriptor SetPower %p\n", Descriptor->Dispatch->SetPower);
+        DPRINT("Descriptor QueryInterface %p\n", Descriptor->Dispatch->QueryInterface);
+    }
 
     /* check for success */
     if (!NT_SUCCESS(Status))
@@ -695,7 +742,7 @@ KsInitializeDevice(
     }
 
     /* initialize IKsDevice interface */
-    Header->lpVtblIKsDevice = &vt_IKsDevice;
+    Header->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsDevice;
     Header->ref = 1;
 
     /* allocate object bag */
@@ -779,7 +826,7 @@ KsReferenceSoftwareBusObject(
      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {
@@ -803,7 +850,7 @@ KsReferenceBusObject(
      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {
@@ -828,7 +875,7 @@ KsDereferenceBusObject(
      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {
@@ -852,7 +899,7 @@ KsDereferenceSoftwareBusObject(
      DPRINT1("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header);
 
      /* get device interface */
-     Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice;
+     Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
 
      if (Device)
      {
index cd0ffe2..c1fdff8 100644 (file)
@@ -90,6 +90,10 @@ KspRegisterDeviceInterfaces(
             /* return result */
             return Status;
         }
+
+        /* copy device class */
+        RtlMoveMemory(&SymEntry->DeviceInterfaceClass, &Categories[Index], sizeof(CLSID));
+
         /* insert symbolic link entry */
         InsertTailList(SymbolicLinkList, &SymEntry->Entry);
     }
index 409977d..c0195a4 100644 (file)
@@ -39,10 +39,19 @@ KsGetDevice(
 {
     PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
 
-    DPRINT("KsGetDevice %p BasicHeader %p Type %x\n", Object, BasicHeader, BasicHeader->Type);
+    DPRINT("KsGetDevice Type %lu KsDevice %p\n", BasicHeader->Type, BasicHeader->KsDevice);
 
-    ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == BasicHeader->Type);
+    ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
     ASSERT(BasicHeader->KsDevice);
+    ASSERT(BasicHeader->KsDevice->Descriptor);
+    ASSERT(BasicHeader->KsDevice->Bag);
+    ASSERT(BasicHeader->KsDevice->Context);
+    ASSERT(BasicHeader->KsDevice->FunctionalDeviceObject);
+    ASSERT(BasicHeader->KsDevice->PhysicalDeviceObject);
+    ASSERT(BasicHeader->KsDevice->NextDeviceObject);
+    ASSERT(BasicHeader->KsDevice->Started);
+    ASSERT(BasicHeader->KsDevice->SystemPowerState == PowerSystemWorking);
+    ASSERT(BasicHeader->KsDevice->DevicePowerState == PowerDeviceD0);
 
     return BasicHeader->KsDevice;
 }
@@ -152,6 +161,8 @@ KsInitializeDriver(
     PKS_DRIVER_EXTENSION DriverObjectExtension;
     NTSTATUS Status = STATUS_SUCCESS;
 
+    DPRINT("KsInitializeDriver\n");
+
     if (Descriptor)
     {
         Status = IoAllocateDriverObjectExtension(DriverObject, (PVOID)KsInitializeDriver, sizeof(KS_DRIVER_EXTENSION), (PVOID*)&DriverObjectExtension);
index 5d06ca2..5f4a74b 100644 (file)
@@ -14,18 +14,15 @@ typedef struct
     KSBASIC_HEADER Header;
     KSFILTER Filter;
 
-    IKsFilterVtbl *lpVtbl;
     IKsControlVtbl *lpVtblKsControl;
     IKsFilterFactory * FilterFactory;
     LONG ref;
 
     PKSIOBJECT_HEADER ObjectHeader;
     KSTOPOLOGY Topology;
-    KSPIN_DESCRIPTOR_EX * PinDescriptorsEx;
-    KSPIN_DESCRIPTOR * PinDescriptors;
-    ULONG PinDescriptorCount;
     PKSFILTERFACTORY Factory;
     PFILE_OBJECT FileObject;
+    KMUTEX ControlMutex;
     KMUTEX ProcessingMutex;
 
 
@@ -34,7 +31,7 @@ typedef struct
 
     ULONG *PinInstanceCount;
     PKSPIN * FirstPin;
-    KSPROCESSPIN_INDEXENTRY ProcessPinIndex;
+    PKSPROCESSPIN_INDEXENTRY ProcessPinIndex;
 
 }IKsFilterImpl;
 
@@ -43,9 +40,17 @@ const GUID IID_IKsFilter  = {0x3ef6ee44L, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc
 const GUID KSPROPSETID_Topology                = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
 const GUID KSPROPSETID_Pin                     = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
 
+VOID
+IKsFilter_RemoveFilterFromFilterFactory(
+    IKsFilterImpl * This,
+    PKSFILTERFACTORY FilterFactory);
+
+NTSTATUS NTAPI FilterTopologyPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER  Request, IN OUT PVOID  Data);
+NTSTATUS NTAPI FilterPinPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER  Request, IN OUT PVOID  Data);
+
 
-DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, KspTopologyPropertyHandler);
-DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, KspPinPropertyHandler, KspPinPropertyHandler, KspPinPropertyHandler);
+DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, FilterTopologyPropertyHandler);
+DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, FilterPinPropertyHandler, FilterPinPropertyHandler, FilterPinPropertyHandler);
 
 KSPROPERTY_SET FilterPropertySet[] =
 {
@@ -76,7 +81,7 @@ IKsControl_fnQueryInterface(
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
     {
-        *Output = &This->lpVtbl;
+        *Output = &This->Header.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
@@ -179,12 +184,13 @@ IKsFilter_fnQueryInterface(
     IN  REFIID refiid,
     OUT PVOID* Output)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    NTSTATUS Status;
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown) ||
         IsEqualGUIDAligned(refiid, &IID_IKsFilter))
     {
-        *Output = &This->lpVtbl;
+        *Output = &This->Header.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
@@ -195,7 +201,20 @@ IKsFilter_fnQueryInterface(
         return STATUS_SUCCESS;
     }
 
-    return STATUS_UNSUCCESSFUL;
+    if (This->Header.ClientAggregate)
+    {
+         /* using client aggregate */
+         Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output);
+
+         if (NT_SUCCESS(Status))
+         {
+             /* client aggregate supports interface */
+             return Status;
+         }
+    }
+
+    DPRINT("IKsFilter_fnQueryInterface no interface\n");
+    return STATUS_NOT_SUPPORTED;
 }
 
 ULONG
@@ -203,7 +222,7 @@ NTAPI
 IKsFilter_fnAddRef(
     IKsFilter * iface)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     return InterlockedIncrement(&This->ref);
 }
@@ -213,7 +232,7 @@ NTAPI
 IKsFilter_fnRelease(
     IKsFilter * iface)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     InterlockedDecrement(&This->ref);
 
@@ -232,7 +251,7 @@ NTAPI
 IKsFilter_fnGetStruct(
     IKsFilter * iface)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     return &This->Filter;
 }
@@ -289,23 +308,25 @@ IKsFilter_fnAddProcessPin(
     IN PKSPROCESSPIN ProcessPin)
 {
     NTSTATUS Status;
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     /* first acquire processing mutex */
     KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
 
-    /* edit process pin descriptor */
-    Status = _KsEdit(This->Filter.Bag,
-                     (PVOID*)&This->ProcessPinIndex.Pins, 
-                     (This->ProcessPinIndex.Count + 1) * sizeof(PKSPROCESSPIN),
-                     (This->ProcessPinIndex.Count) * sizeof(PKSPROCESSPIN),
+    /* sanity check */
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > ProcessPin->Pin->Id);
+
+    /* allocate new process pin array */
+    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex[ProcessPin->Pin->Id].Pins,
+                     (This->Filter.Descriptor->PinDescriptorsCount + 1) * sizeof(PKSPROCESSPIN),
+                     This->Filter.Descriptor->PinDescriptorsCount * sizeof(PKSPROCESSPIN),
                      0);
 
     if (NT_SUCCESS(Status))
     {
-        /* add new process pin */
-        This->ProcessPinIndex.Pins[This->ProcessPinIndex.Count] = ProcessPin;
-        This->ProcessPinIndex.Count++;
+        /* store process pin */
+        This->ProcessPinIndex[ProcessPin->Pin->Id].Pins[This->ProcessPinIndex[ProcessPin->Pin->Id].Count] = ProcessPin;
+        This->ProcessPinIndex[ProcessPin->Pin->Id].Count++;
     }
 
     /* release process mutex */
@@ -321,25 +342,39 @@ IKsFilter_fnRemoveProcessPin(
     IN PKSPROCESSPIN ProcessPin)
 {
     ULONG Index;
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    ULONG Count;
+    PKSPROCESSPIN * Pins;
+
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     /* first acquire processing mutex */
     KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
 
-    /* iterate through process pin index array and search for the process pin to be removed */
-    for(Index = 0; Index < This->ProcessPinIndex.Count; Index++)
+    /* sanity check */
+    ASSERT(ProcessPin->Pin);
+    ASSERT(ProcessPin->Pin->Id);
+
+    Count = This->ProcessPinIndex[ProcessPin->Pin->Id].Count;
+    Pins =  This->ProcessPinIndex[ProcessPin->Pin->Id].Pins;
+
+    /* search for current process pin */
+    for(Index = 0; Index < Count; Index++)
     {
-        if (This->ProcessPinIndex.Pins[Index] == ProcessPin)
+        if (Pins[Index] == ProcessPin)
         {
-            /* found process pin */
-            if (Index + 1 < This->ProcessPinIndex.Count)
-            {
-                /* erase entry */
-                RtlMoveMemory(&This->ProcessPinIndex.Pins[Index], &This->ProcessPinIndex.Pins[Index+1], This->ProcessPinIndex.Count - Index - 1);
-            }
-            /* decrement process pin count */
-            This->ProcessPinIndex.Count--;
+            RtlMoveMemory(&Pins[Index], &Pins[Index + 1], (Count - (Index + 1)) * sizeof(PKSPROCESSPIN));
+            break;
         }
+
+    }
+
+    /* decrement pin count */
+    This->ProcessPinIndex[ProcessPin->Pin->Id].Count--;
+
+    if (!This->ProcessPinIndex[ProcessPin->Pin->Id].Count)
+    {
+        /* clear entry object bag will delete it */
+       This->ProcessPinIndex[ProcessPin->Pin->Id].Pins = NULL;
     }
 
     /* release process mutex */
@@ -394,8 +429,9 @@ NTAPI
 IKsFilter_fnGetProcessDispatch(
     IKsFilter * iface)
 {
-    UNIMPLEMENTED
-    return NULL;
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
+
+    return This->ProcessPinIndex;
 }
 
 static IKsFilterVtbl vt_IKsFilter =
@@ -472,13 +508,13 @@ IKsFilter_DispatchClose(
         return Status;
 
     /* get our real implementation */
-    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl);
+    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown);
 
     /* does the driver support notifications */
-    if (This->Factory->FilterDescriptor && This->Factory->FilterDescriptor->Dispatch && This->Factory->FilterDescriptor->Dispatch->Close)
+    if (This->Filter.Descriptor && This->Filter.Descriptor->Dispatch && This->Filter.Descriptor->Dispatch->Close)
     {
         /* call driver's filter close function */
-        Status = This->Factory->FilterDescriptor->Dispatch->Close(&This->Filter, Irp);
+        Status = This->Filter.Descriptor->Dispatch->Close(&This->Filter, Irp);
     }
 
     if (NT_SUCCESS(Status) && Status != STATUS_PENDING)
@@ -488,8 +524,8 @@ IKsFilter_DispatchClose(
         /* complete irp */
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-        /* FIXME remove our instance from the filter factory */
-        ASSERT(0);
+        /* remove our instance from the filter factory */
+        IKsFilter_RemoveFilterFromFilterFactory(This, This->Factory);
 
         /* free object header */
         KsFreeObjectHeader(This->ObjectHeader);
@@ -517,7 +553,7 @@ KspHandlePropertyInstances(
     KSPIN_CINSTANCES * Instances;
     KSP_PIN * Pin = (KSP_PIN*)Request;
 
-    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
+    if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -525,12 +561,12 @@ KspHandlePropertyInstances(
     }
 
     /* ignore custom structs for now */
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->PinDescriptorCount > Pin->PinId);
+    ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
 
     Instances = (KSPIN_CINSTANCES*)Data;
     /* max instance count */
-    Instances->PossibleCount = This->PinDescriptorsEx[Pin->PinId].InstancesPossible;
+    Instances->PossibleCount = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesPossible;
     /* current instance count */
     Instances->CurrentCount = This->PinInstanceCount[Pin->PinId];
 
@@ -549,7 +585,7 @@ KspHandleNecessaryPropertyInstances(
     PULONG Result;
     KSP_PIN * Pin = (KSP_PIN*)Request;
 
-    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
+    if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -557,11 +593,11 @@ KspHandleNecessaryPropertyInstances(
     }
 
     /* ignore custom structs for now */
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->PinDescriptorCount > Pin->PinId);
+    ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
 
     Result = (PULONG)Data;
-    *Result = This->PinDescriptorsEx[Pin->PinId].InstancesNecessary;
+    *Result = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesNecessary;
 
     IoStatus->Information = sizeof(ULONG);
     IoStatus->Status = STATUS_SUCCESS;
@@ -581,13 +617,23 @@ KspHandleDataIntersection(
     PKSDATARANGE DataRange;
     NTSTATUS Status = STATUS_NO_MATCH;
     ULONG Index, Length;
+    PIO_STACK_LOCATION IoStack;
     KSP_PIN * Pin = (KSP_PIN*)Request;
 
+    /* get stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* sanity check */
+    ASSERT(DataLength == IoStack->Parameters.DeviceIoControl.OutputBufferLength);
+
     /* Access parameters */
     MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
     DataRange = (PKSDATARANGE)(MultipleItem + 1);
 
-    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
+    /* FIXME make sure its 64 bit aligned */
+    ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
+
+    if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -595,12 +641,12 @@ KspHandleDataIntersection(
     }
 
     /* ignore custom structs for now */
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->PinDescriptorCount > Pin->PinId);
+    ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
 
-    if (This->PinDescriptorsEx[Pin->PinId].IntersectHandler == NULL ||
-        This->PinDescriptors[Pin->PinId].DataRanges == NULL ||
-        This->PinDescriptors[Pin->PinId].DataRangesCount == 0)
+    if (This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler == NULL ||
+        This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges == NULL ||
+        This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRangesCount == 0)
     {
         /* no driver supported intersect handler / no provided data ranges */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -609,31 +655,65 @@ KspHandleDataIntersection(
 
     for(Index = 0; Index < MultipleItem->Count; Index++)
     {
+        UNICODE_STRING MajorFormat, SubFormat, Specifier;
+        /* convert the guid to string */
+        RtlStringFromGUID(&DataRange->MajorFormat, &MajorFormat);
+        RtlStringFromGUID(&DataRange->SubFormat, &SubFormat);
+        RtlStringFromGUID(&DataRange->Specifier, &Specifier);
+
+        DPRINT("KspHandleDataIntersection Index %lu PinId %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index, Pin->PinId, MajorFormat.Buffer, SubFormat.Buffer, Specifier.Buffer,
+               DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment, DataRange->Flags, DataRange->Reserved, DataLength);
+
+        /* FIXME implement KsPinDataIntersectionEx */
         /* Call miniport's properitary handler */
-        Status = This->PinDescriptorsEx[Pin->PinId].IntersectHandler(NULL, /* context */
-                                                                     Irp,
-                                                                     Pin,
-                                                                     DataRange,
-                                                                    (PKSDATAFORMAT)This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges,
-                                                                     DataLength,
-                                                                     Data,
-                                                                     &Length);
-
-        if (Status == STATUS_SUCCESS)
+        Status = This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler(&This->Filter,
+                                                                                      Irp,
+                                                                                      Pin,
+                                                                                      DataRange,
+                                                                                      This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */
+                                                                                      DataLength,
+                                                                                      Data,
+                                                                                      &Length);
+        DPRINT("KspHandleDataIntersection Status %lx\n", Status);
+
+        if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
         {
+            ASSERT(Length);
             IoStatus->Information = Length;
             break;
         }
+
         DataRange =  UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize);
+        /* FIXME make sure its 64 bit aligned */
+        ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
     }
-
     IoStatus->Status = Status;
     return Status;
 }
 
 NTSTATUS
 NTAPI
-KspPinPropertyHandler(
+FilterTopologyPropertyHandler(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER  Request,
+    IN OUT PVOID  Data)
+{
+    IKsFilterImpl * This;
+
+    /* get filter implementation */
+    This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
+
+    /* sanity check */
+    ASSERT(This);
+
+    return KsTopologyPropertyHandler(Irp, Request, Data, &This->Topology);
+
+}
+
+
+NTSTATUS
+NTAPI
+FilterPinPropertyHandler(
     IN PIRP Irp,
     IN PKSIDENTIFIER  Request,
     IN OUT PVOID  Data)
@@ -645,6 +725,9 @@ KspPinPropertyHandler(
     /* get filter implementation */
     This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
 
+    /* sanity check */
+    ASSERT(This);
+
     /* get current stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
@@ -658,8 +741,8 @@ KspPinPropertyHandler(
         case KSPROPERTY_PIN_COMMUNICATION:
         case KSPROPERTY_PIN_CATEGORY:
         case KSPROPERTY_PIN_NAME:
-        case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
-            Status = KsPinPropertyHandler(Irp, Request, Data, This->PinDescriptorCount, This->PinDescriptors);
+        case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
+            Status = KspPinPropertyHandler(Irp, Request, Data, This->Filter.Descriptor->PinDescriptorsCount, (const KSPIN_DESCRIPTOR*)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize);
             break;
         case KSPROPERTY_PIN_GLOBALCINSTANCES:
             Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, TRUE);
@@ -674,16 +757,11 @@ KspPinPropertyHandler(
         case KSPROPERTY_PIN_DATAINTERSECTION:
             Status = KspHandleDataIntersection(Irp, &Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This);
             break;
-        case KSPROPERTY_PIN_PHYSICALCONNECTION:
-        case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
-            UNIMPLEMENTED
-            Status = STATUS_NOT_IMPLEMENTED;
-            break;
         default:
             UNIMPLEMENTED
-            Status = STATUS_UNSUCCESSFUL;
+            Status = STATUS_NOT_FOUND;
     }
-    DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->PinDescriptorCount, Request->Id, Status);
+    //DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->PinDescriptorCount, Request->Id, Status);
 
 
     return Status;
@@ -700,6 +778,9 @@ IKsFilter_DispatchDeviceIoControl(
     IKsFilterImpl * This;
     NTSTATUS Status;
     PKSFILTER FilterInstance;
+    UNICODE_STRING GuidString;
+    PKSPROPERTY Property;
+    ULONG SetCount = 0;
 
     /* obtain filter from object header */
     Status = IKsFilter_GetFilterFromIrp(Irp, &Filter);
@@ -707,45 +788,96 @@ IKsFilter_DispatchDeviceIoControl(
         return Status;
 
     /* get our real implementation */
-    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl);
+    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown);
 
     /* current irp stack */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
+    /* get property from input buffer */
+    Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+    /* get filter instance */
+    FilterInstance = Filter->lpVtbl->GetStruct(Filter);
+
+    /* sanity check */
+    ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER));
+    ASSERT(FilterInstance);
+    ASSERT(FilterInstance->Descriptor);
+    ASSERT(FilterInstance->Descriptor->AutomationTable);
+
+    /* acquire control mutex */
+    KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
+
+    if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD)
     {
-        UNIMPLEMENTED;
+        const KSMETHOD_SET *MethodSet = NULL;
+        ULONG MethodItemSize = 0;
 
-        /* release filter interface */
-        Filter->lpVtbl->Release(Filter);
+        /* check if the driver supports method sets */
+        if (FilterInstance->Descriptor->AutomationTable->MethodSetsCount)
+        {
+            SetCount = FilterInstance->Descriptor->AutomationTable->MethodSetsCount;
+            MethodSet = FilterInstance->Descriptor->AutomationTable->MethodSets;
+            MethodItemSize = FilterInstance->Descriptor->AutomationTable->MethodItemSize;
+        }
 
-        /* complete and forget irp */
-        Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-        return STATUS_NOT_IMPLEMENTED;
+        /* call method set handler */
+        Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL, MethodItemSize);
     }
+    else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
+    {
+        const KSPROPERTY_SET *PropertySet = NULL;
+        ULONG PropertyItemSize = 0;
+
+        /* check if the driver supports method sets */
+        if (FilterInstance->Descriptor->AutomationTable->PropertySetsCount)
+        {
+            SetCount = FilterInstance->Descriptor->AutomationTable->PropertySetsCount;
+            PropertySet = FilterInstance->Descriptor->AutomationTable->PropertySets;
+            PropertyItemSize = FilterInstance->Descriptor->AutomationTable->PropertyItemSize;
+        }
 
-    /* call property handler supported by ks */
-    KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This;
-    Status = KspPropertyHandler(Irp, 2, FilterPropertySet, NULL, sizeof(KSPROPERTY_ITEM));
+        /* needed for our property handlers */
+        KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This;
 
-    if (Status == STATUS_NOT_FOUND)
+        /* call property handler */
+        Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize);
+    }
+    else
     {
-        /* get filter instance */
-        FilterInstance = Filter->lpVtbl->GetStruct(Filter);
+        /* sanity check */
+        ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT ||
+               IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT);
 
-        /* check if the driver supports property sets */
-        if (FilterInstance->Descriptor->AutomationTable && FilterInstance->Descriptor->AutomationTable->PropertySetsCount)
+        if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
+        {
+            /* call enable event handlers */
+            Status = KspEnableEvent(Irp,
+                                    FilterInstance->Descriptor->AutomationTable->EventSetsCount,
+                                    (PKSEVENT_SET)FilterInstance->Descriptor->AutomationTable->EventSets,
+                                    &This->Header.EventList,
+                                    KSEVENTS_SPINLOCK,
+                                    (PVOID)&This->Header.EventListLock,
+                                    NULL,
+                                    FilterInstance->Descriptor->AutomationTable->EventItemSize);
+        }
+        else
         {
-            /* call driver's filter property handler */
-            Status = KspPropertyHandler(Irp, 
-                                        FilterInstance->Descriptor->AutomationTable->PropertySetsCount,
-                                        FilterInstance->Descriptor->AutomationTable->PropertySets, 
-                                        NULL,
-                                        FilterInstance->Descriptor->AutomationTable->PropertyItemSize);
+            /* disable event handler */
+            Status = KsDisableEvent(Irp, &This->Header.EventList, KSEVENTS_SPINLOCK, &This->Header.EventListLock);
         }
     }
 
+    RtlStringFromGUID(&Property->Set, &GuidString);
+    DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information);
+    RtlFreeUnicodeString(&GuidString);
+
+    /* release filter */
+    Filter->lpVtbl->Release(Filter);
+
+    /* release control mutex */
+    KeReleaseMutex(This->Header.ControlMutex, FALSE);
+
     if (Status != STATUS_PENDING)
     {
         Irp->IoStatus.Status = Status;
@@ -782,9 +914,7 @@ IKsFilter_CreateDescriptors(
     /* initialize pin descriptors */
     This->FirstPin = NULL;
     This->PinInstanceCount = NULL;
-    This->PinDescriptors = NULL;
-    This->PinDescriptorsEx = NULL;
-    This->PinDescriptorCount = 0;
+    This->ProcessPinIndex = NULL;
 
     /* initialize topology descriptor */
     This->Topology.CategoriesCount = FilterDescriptor->CategoriesCount;
@@ -803,18 +933,8 @@ IKsFilter_CreateDescriptors(
         ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
 
         /* store pin descriptors ex */
-        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount,
-                         sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount, 0);
-
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
-            return Status;
-        }
-
-        /* store pin descriptors */
-        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount,
-                         sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount, 0);
+        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount,
+                         FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, 0);
 
         if (!NT_SUCCESS(Status))
         {
@@ -822,7 +942,7 @@ IKsFilter_CreateDescriptors(
             return Status;
         }
 
-        /* store pin instance count ex */
+        /* store pin instance count */
         Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinInstanceCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount,
                          sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 0);
 
@@ -842,18 +962,33 @@ IKsFilter_CreateDescriptors(
             return Status;
         }
 
-
-
         /* add new pin factory */
-        RtlMoveMemory(This->PinDescriptorsEx, FilterDescriptor->PinDescriptors, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount);
+        RtlMoveMemory((PVOID)This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount);
 
-        for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++)
+        /* allocate process pin index */
+        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount,
+                         sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount, 0);
+
+        if (!NT_SUCCESS(Status))
         {
-            RtlMoveMemory(&This->PinDescriptors[Index], &FilterDescriptor->PinDescriptors[Index].PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
+            DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
+            return Status;
         }
 
-        /* store new pin descriptor count */
-        This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount;
+    }
+
+
+    if (FilterDescriptor->ConnectionsCount)
+    {
+        /* modify connections array */
+        Status = _KsEdit(This->Filter.Bag,
+                        (PVOID*)&This->Filter.Descriptor->Connections,
+                         FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
+                         FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
+                         0);
+
+       This->Topology.TopologyConnections = This->Filter.Descriptor->Connections;
+       This->Topology.TopologyConnectionsCount = ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount = FilterDescriptor->ConnectionsCount;
     }
 
     if (FilterDescriptor->NodeDescriptorsCount)
@@ -905,6 +1040,7 @@ IKsFilter_CopyFilterDescriptor(
     const KSFILTER_DESCRIPTOR* FilterDescriptor)
 {
     NTSTATUS Status;
+    KSAUTOMATION_TABLE AutomationTable;
 
     This->Filter.Descriptor = AllocateItem(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR));
     if (!This->Filter.Descriptor)
@@ -921,27 +1057,39 @@ IKsFilter_CopyFilterDescriptor(
     /* copy filter descriptor fields */
     RtlMoveMemory((PVOID)This->Filter.Descriptor, FilterDescriptor, sizeof(KSFILTER_DESCRIPTOR));
 
+    /* zero automation table */
+    RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE));
+
+    /* setup filter property sets */
+    AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM);
+    AutomationTable.PropertySetsCount = 2;
+    AutomationTable.PropertySets = FilterPropertySet;
+
+    /* merge filter automation table */
+    Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Filter.Descriptor->AutomationTable, (PKSAUTOMATION_TABLE)FilterDescriptor->AutomationTable, &AutomationTable, This->Filter.Bag);
+
     return Status;
 }
 
 
-NTSTATUS
+VOID
 IKsFilter_AddPin(
-    IKsFilter * Filter,
+    PKSFILTER Filter,
     PKSPIN Pin)
 {
     PKSPIN NextPin, CurPin;
     PKSBASIC_HEADER BasicHeader;
-    IKsFilterImpl * This = (IKsFilterImpl*)Filter;
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
     /* sanity check */
-    ASSERT(Pin->Id < This->PinDescriptorCount);
+    ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
 
     if (This->FirstPin[Pin->Id] == NULL)
     {
         /* welcome first pin */
         This->FirstPin[Pin->Id] = Pin;
-        return STATUS_SUCCESS;
+        This->PinInstanceCount[Pin->Id]++;
+        return;
     }
 
     /* get first pin */
@@ -963,8 +1111,58 @@ IKsFilter_AddPin(
 
     /* store pin */
     BasicHeader->Next.Pin = Pin;
+}
 
-    return STATUS_SUCCESS;
+VOID
+IKsFilter_RemovePin(
+    PKSFILTER Filter,
+    PKSPIN Pin)
+{
+    PKSPIN NextPin, CurPin, LastPin;
+    PKSBASIC_HEADER BasicHeader;
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
+
+    /* sanity check */
+    ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
+
+    /* get first pin */
+    CurPin = This->FirstPin[Pin->Id];
+
+    LastPin = NULL;
+    do
+    {
+        /* get next instantiated pin */
+        NextPin = KsPinGetNextSiblingPin(CurPin);
+
+        if (CurPin == Pin)
+        {
+            if (LastPin)
+            {
+                /* get basic header of last pin */
+                BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastPin - sizeof(KSBASIC_HEADER));
+
+                BasicHeader->Next.Pin = NextPin;
+            }
+            else
+            {
+                /* erase last pin */
+                This->FirstPin[Pin->Id] = NextPin;
+            }
+            /* decrement pin instance count */
+            This->PinInstanceCount[Pin->Id]--;
+            return;
+        }
+
+        if (!NextPin)
+            break;
+
+        LastPin = CurPin;
+        NextPin = CurPin;
+
+    }while(NextPin != NULL);
+
+    /* pin not found */
+    ASSERT(0);
 }
 
 
@@ -991,45 +1189,39 @@ IKsFilter_DispatchCreatePin(
     ASSERT(This->Header.Type == KsObjectTypeFilter);
 
     /* acquire control mutex */
-    KeWaitForSingleObject(&This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
+    KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
 
     /* now validate the connect request */
-    Status = KsValidateConnectRequest(Irp, This->PinDescriptorCount, This->PinDescriptors, &Connect);
+    Status = KspValidateConnectRequest(Irp, This->Filter.Descriptor->PinDescriptorsCount, (PVOID)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize, &Connect);
 
     DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status);
 
     if (NT_SUCCESS(Status))
     {
         /* sanity check */
-        ASSERT(Connect->PinId < This->PinDescriptorCount);
+        ASSERT(Connect->PinId < This->Filter.Descriptor->PinDescriptorsCount);
 
         DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect->PinId, 
                This->PinInstanceCount[Connect->PinId],
-               This->PinDescriptorsEx[Connect->PinId].InstancesPossible);
+               This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible);
 
-        if (This->PinInstanceCount[Connect->PinId] < This->PinDescriptorsEx[Connect->PinId].InstancesPossible)
+        if (This->PinInstanceCount[Connect->PinId] < This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible)
         {
             /* create the pin */
-            Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->lpVtbl, Connect, &This->PinDescriptorsEx[Connect->PinId]);
+            Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->Header.OuterUnknown, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[Connect->PinId]);
 
             DPRINT("IKsFilter_DispatchCreatePin  KspCreatePin %lx\n", Status);
-
-            if (NT_SUCCESS(Status))
-            {
-                /* successfully created pin, increment pin instance count */
-                This->PinInstanceCount[Connect->PinId]++;
-            }
         }
         else
         {
             /* maximum instance count reached, bye-bye */
             Status = STATUS_UNSUCCESSFUL;
-            DPRINT("IKsFilter_DispatchCreatePin  MaxInstance %lu CurInstance %lu %lx\n", This->PinDescriptorsEx[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]);
+            DPRINT("IKsFilter_DispatchCreatePin  MaxInstance %lu CurInstance %lu %lx\n", This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]);
         }
     }
 
     /* release control mutex */
-    KeReleaseMutex(&This->Header.ControlMutex, FALSE);
+    KeReleaseMutex(This->Header.ControlMutex, FALSE);
 
     if (Status != STATUS_PENDING)
     {
@@ -1098,12 +1290,72 @@ IKsFilter_AttachFilterToFilterFactory(
             /* found last entry */
             break;
         }
-    }while(FilterFactory);
+    }while(TRUE);
 
     /* attach filter factory */
     BasicHeader->Next.Filter = &This->Filter;
 }
 
+VOID
+IKsFilter_RemoveFilterFromFilterFactory(
+    IKsFilterImpl * This,
+    PKSFILTERFACTORY FilterFactory)
+{
+    PKSBASIC_HEADER BasicHeader;
+    PKSFILTER Filter, LastFilter;
+
+    /* get filter factory basic header */
+    BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER));
+
+    /* sanity check */
+    ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory);
+    ASSERT(BasicHeader->FirstChild.Filter != NULL);
+
+
+    /* set to first entry */
+    Filter = BasicHeader->FirstChild.Filter;
+    LastFilter = NULL;
+
+    do
+    {
+         if (Filter == &This->Filter)
+         {
+             if (LastFilter)
+             {
+                 /* get basic header */
+                 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastFilter - sizeof(KSBASIC_HEADER));
+                 /* remove filter instance */
+                 BasicHeader->Next.Filter = This->Header.Next.Filter;
+                 break;
+             }
+             else
+             {
+                 /* remove filter instance */
+                 BasicHeader->FirstChild.Filter = This->Header.Next.Filter;
+                 break;
+             }
+         }
+
+        /* get basic header */
+        BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER));
+        /* sanity check */
+        ASSERT(BasicHeader->Type == KsObjectTypeFilter);
+
+        LastFilter = Filter;
+        if (BasicHeader->Next.Filter)
+        {
+            /* iterate to next filter factory */
+            Filter = BasicHeader->Next.Filter;
+        }
+        else
+        {
+            /* filter is not in list */
+            ASSERT(0);
+            break;
+        }
+    }while(TRUE);
+}
+
 NTSTATUS
 NTAPI
 KspCreateFilter(
@@ -1148,7 +1400,7 @@ KspCreateFilter(
         DPRINT("KspCreateFilter OutOfMemory\n");
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-    KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
+    KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
     KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL);
 
     /* copy filter descriptor */
@@ -1176,6 +1428,8 @@ KspCreateFilter(
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
+    DPRINT("KspCreateFilter Flags %lx\n", Factory->FilterDescriptor->Flags);
+
     /* initialize pin create item */
     CreateItem[0].Create = IKsFilter_DispatchCreatePin;
     CreateItem[0].Context = (PVOID)This;
@@ -1190,10 +1444,9 @@ KspCreateFilter(
 
     /* initialize filter instance */
     This->ref = 1;
-    This->lpVtbl = &vt_IKsFilter;
+    This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter;
     This->lpVtblKsControl = &vt_IKsControl;
 
-    This->Filter.Descriptor = Factory->FilterDescriptor;
     This->Factory = Factory;
     This->FilterFactory = iface;
     This->FileObject = IoStack->FileObject;
@@ -1202,7 +1455,8 @@ KspCreateFilter(
     This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice;
     This->Header.Parent.KsFilterFactory = iface->lpVtbl->GetStruct(iface);
     This->Header.Type = KsObjectTypeFilter;
-    KeInitializeMutex(&This->Header.ControlMutex, 0);
+    This->Header.ControlMutex = &This->ControlMutex;
+    KeInitializeMutex(This->Header.ControlMutex, 0);
     InitializeListHead(&This->Header.EventList);
     KeInitializeSpinLock(&This->Header.EventListLock);
 
@@ -1224,8 +1478,9 @@ KspCreateFilter(
         if (Factory->FilterDescriptor->Dispatch->Create)
         {
             /* now let driver initialize the filter instance */
-            DPRINT("Before instantiating filter Filter %p This %p KSBASIC_HEADER %u\n", &This->Filter, This, sizeof(KSBASIC_HEADER));
+
             ASSERT(This->Header.KsDevice);
+            ASSERT(This->Header.KsDevice->Started);
             Status = Factory->FilterDescriptor->Dispatch->Create(&This->Filter, Irp);
 
             if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
@@ -1253,14 +1508,14 @@ KspCreateFilter(
 
     /* initialize object header extra fields */
     This->ObjectHeader->Type = KsObjectTypeFilter;
-    This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
+    This->ObjectHeader->Unknown = (PUNKNOWN)&This->Header.OuterUnknown;
     This->ObjectHeader->ObjectType = (PVOID)&This->Filter;
 
     /* attach filter to filter factory */
     IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory);
 
     /* completed initialization */
-    DPRINT("KspCreateFilter done %lx\n", Status);
+    DPRINT("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice);
     return Status;
 }
 
@@ -1292,6 +1547,7 @@ KsFilterReleaseProcessingMutex(
     KeReleaseMutex(&This->ProcessingMutex, FALSE);
 }
 
+
 /*
     @implemented
 */
@@ -1304,40 +1560,42 @@ KsFilterAddTopologyConnections (
     IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections)
 {
     ULONG Count;
-    KSTOPOLOGY_CONNECTION * Connections;
+    NTSTATUS Status;
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
+    DPRINT("KsFilterAddTopologyConnections\n");
+
+    ASSERT(This->Filter.Descriptor);
     Count = This->Filter.Descriptor->ConnectionsCount + NewConnectionsCount;
 
-    /* allocate array */
-    Connections = AllocateItem(NonPagedPool, Count * sizeof(KSTOPOLOGY_CONNECTION));
-    if (!Connections)
-        return STATUS_INSUFFICIENT_RESOURCES;
 
-    /* FIXME verify connections */
+    /* modify connections array */
+    Status = _KsEdit(This->Filter.Bag,
+                    (PVOID*)&This->Filter.Descriptor->Connections,
+                     Count * sizeof(KSTOPOLOGY_CONNECTION),
+                     This->Filter.Descriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
+                     0);
 
-    if (This->Filter.Descriptor->ConnectionsCount)
+    if (!NT_SUCCESS(Status))
     {
-        /* copy old connections */
-        RtlMoveMemory(Connections, This->Filter.Descriptor->Connections, sizeof(KSTOPOLOGY_CONNECTION) * This->Filter.Descriptor->ConnectionsCount);
+        /* failed */
+        DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status);
+        return Status;
     }
 
-    /* add new connections */
-    RtlMoveMemory((PVOID)(Connections + This->Filter.Descriptor->ConnectionsCount), NewTopologyConnections, NewConnectionsCount);
-
-    /* add the new connections */
-    RtlMoveMemory((PVOID)&This->Filter.Descriptor->ConnectionsCount, &Count, sizeof(ULONG)); /* brain-dead gcc hack */
+    /* FIXME verify connections */
 
-    /* free old connections array */
-    if (This->Filter.Descriptor->ConnectionsCount)
-    {
-        FreeItem((PVOID)This->Filter.Descriptor->Connections);
-    }
+    /* copy new connections */
+    RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections[This->Filter.Descriptor->ConnectionsCount],
+                  NewTopologyConnections,
+                  NewConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION));
 
-    /* brain-dead gcc hack */
-    RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections, Connections, sizeof(KSTOPOLOGY_CONNECTION*));
+    /* update topology */
+    This->Topology.TopologyConnectionsCount += NewConnectionsCount;
+    ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount += NewConnectionsCount;
+    This->Topology.TopologyConnections = This->Filter.Descriptor->Connections;
 
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 /*
@@ -1386,13 +1644,13 @@ KsFilterCreatePinFactory (
     DPRINT("KsFilterCreatePinFactory\n");
 
     /* calculate new count */
-    Count = This->PinDescriptorCount + 1;
+    Count = This->Filter.Descriptor->PinDescriptorsCount + 1;
 
     /* sanity check */
     ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
 
-    /* allocate pin descriptors ex array */
-    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, Count * sizeof(KSPIN_DESCRIPTOR_EX), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR_EX), 0);
+    /* modify pin descriptors ex array */
+    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, Count * This->Filter.Descriptor->PinDescriptorSize, This->Filter.Descriptor->PinDescriptorsCount * This->Filter.Descriptor->PinDescriptorSize, 0);
     if (!NT_SUCCESS(Status))
     {
         /* failed */
@@ -1400,8 +1658,8 @@ KsFilterCreatePinFactory (
         return Status;
     }
 
-    /* allocate pin descriptors array */
-    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, Count * sizeof(KSPIN_DESCRIPTOR), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR), 0);
+    /* modify pin instance count array */
+    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->Filter.Descriptor->PinDescriptorsCount, 0);
     if (!NT_SUCCESS(Status))
     {
         /* failed */
@@ -1409,9 +1667,8 @@ KsFilterCreatePinFactory (
         return Status;
     }
 
-
-    /* allocate pin instance count array */
-    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->PinDescriptorCount, 0);
+    /* modify first pin array */
+    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->Filter.Descriptor->PinDescriptorsCount, 0);
     if (!NT_SUCCESS(Status))
     {
         /* failed */
@@ -1419,24 +1676,24 @@ KsFilterCreatePinFactory (
         return Status;
     }
 
-    /* allocate first pin array */
-    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->PinDescriptorCount, 0);
+    /* add new pin factory */
+    RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors[This->Filter.Descriptor->PinDescriptorsCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
+
+    /* allocate process pin index */
+    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * Count,
+                     sizeof(KSPROCESSPIN_INDEXENTRY) * This->Filter.Descriptor->PinDescriptorsCount, 0);
+
     if (!NT_SUCCESS(Status))
     {
-        /* failed */
-        DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
+        DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status);
         return Status;
     }
 
-    /* add new pin factory */
-    RtlMoveMemory(&This->PinDescriptorsEx[This->PinDescriptorCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
-    RtlMoveMemory(&This->PinDescriptors[This->PinDescriptorCount], &InPinDescriptor->PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
-
     /* store new pin id */
-    *PinID = This->PinDescriptorCount;
+    *PinID = This->Filter.Descriptor->PinDescriptorsCount;
 
     /* increment pin descriptor count */
-    This->PinDescriptorCount++;
+    ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->PinDescriptorsCount++;
 
 
     DPRINT("KsFilterCreatePinFactory done\n");
@@ -1469,7 +1726,7 @@ KsFilterGetChildPinCount(
 {
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
-    if (PinId >= This->PinDescriptorCount)
+    if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* index is out of bounds */
         return 0;
@@ -1490,7 +1747,7 @@ KsFilterGetFirstChildPin(
 {
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
-    if (PinId >= This->PinDescriptorCount)
+    if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* index is out of bounds */
         return NULL;
@@ -1529,6 +1786,8 @@ KsGetFilterFromIrp(
     PIO_STACK_LOCATION IoStack;
     PKSIOBJECT_HEADER ObjectHeader;
 
+    DPRINT("KsGetFilterFromIrp\n");
+
     /* get current irp stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
index a16b290..e60bfc4 100644 (file)
@@ -14,13 +14,14 @@ typedef struct
     KSBASIC_HEADER Header;
     KSFILTERFACTORY FilterFactory;
 
-    IKsFilterFactoryVtbl *lpVtbl;
     LONG ref;
     PKSIDEVICE_HEADER DeviceHeader;
     PFNKSFILTERFACTORYPOWER SleepCallback;
     PFNKSFILTERFACTORYPOWER WakeCallback;
 
     LIST_ENTRY SymbolicLinkList;
+    KMUTEX ControlMutex;
+
 }IKsFilterFactoryImpl;
 
 VOID
@@ -57,7 +58,7 @@ IKsFilterFactory_Create(
     Factory = (IKsFilterFactoryImpl*)CONTAINING_RECORD(CreateItem->Context, IKsFilterFactoryImpl, FilterFactory);
 
     /* get interface */
-    iface = (IKsFilterFactory*)&Factory->lpVtbl;
+    iface = (IKsFilterFactory*)&Factory->Header.OuterUnknown;
 
     /* create a filter instance */
     Status = KspCreateFilter(DeviceObject, Irp, iface);
@@ -82,15 +83,31 @@ IKsFilterFactory_fnQueryInterface(
     IN  REFIID refiid,
     OUT PVOID* Output)
 {
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    NTSTATUS Status;
+
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
     {
-        *Output = &This->lpVtbl;
+        *Output = &This->Header.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
-    return STATUS_UNSUCCESSFUL;
+
+    if (This->Header.ClientAggregate)
+    {
+         /* using client aggregate */
+         Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output);
+
+         if (NT_SUCCESS(Status))
+         {
+             /* client aggregate supports interface */
+             return Status;
+         }
+    }
+
+    DPRINT("IKsFilterFactory_fnQueryInterface no interface\n");
+    return STATUS_NOT_SUPPORTED;
 }
 
 ULONG
@@ -98,7 +115,7 @@ NTAPI
 IKsFilterFactory_fnAddRef(
     IKsFilterFactory * iface)
 {
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     return InterlockedIncrement(&This->ref);
 }
@@ -108,7 +125,7 @@ NTAPI
 IKsFilterFactory_fnRelease(
     IKsFilterFactory * iface)
 {
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     InterlockedDecrement(&This->ref);
 
@@ -134,7 +151,7 @@ NTAPI
 IKsFilterFactory_fnGetStruct(
     IKsFilterFactory * iface)
 {
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     return &This->FilterFactory;
 }
@@ -145,7 +162,7 @@ IKsFilterFactory_fnSetDeviceClassesState(
     IKsFilterFactory * iface,
     IN BOOLEAN Enable)
 {
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     return KspSetDeviceInterfacesState(&This->SymbolicLinkList, Enable);
 }
@@ -211,7 +228,7 @@ IKsFilterFactory_fnInitialize(
     BOOL FreeString = FALSE;
     IKsDevice * KsDevice;
 
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
+    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown);
 
     /* get device extension */
     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -225,17 +242,16 @@ IKsFilterFactory_fnInitialize(
     This->Header.Parent.KsDevice = &DeviceExtension->DeviceHeader->KsDevice;
     This->DeviceHeader = DeviceExtension->DeviceHeader;
 
+    /* initialize filter factory control mutex */
+    This->Header.ControlMutex = &This->ControlMutex;
+    KeInitializeMutex(This->Header.ControlMutex, 0);
+
     /* unused fields */
-    KeInitializeMutex(&This->Header.ControlMutex, 0);
     InitializeListHead(&This->Header.EventList);
     KeInitializeSpinLock(&This->Header.EventListLock);
 
-
     InitializeListHead(&This->SymbolicLinkList);
 
-    /* initialize filter factory control mutex */
-    KeInitializeMutex(&This->Header.ControlMutex, 0);
-
     /* does the device use a reference string */
     if (RefString || !Descriptor->ReferenceGuid)
     {
@@ -305,7 +321,7 @@ IKsFilterFactory_fnInitialize(
         if (This->FilterFactory.Bag)
         {
             /* initialize object bag */
-            KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
+            KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
             KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->FilterFactory.Bag, NULL);
         }
     }
@@ -356,10 +372,10 @@ KspCreateFilterFactory(
 
     /* initialize struct */
     This->ref = 1;
-    This->lpVtbl = &vt_IKsFilterFactoryVtbl;
+    This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilterFactoryVtbl;
 
     /* map to com object */
-    Filter = (IKsFilterFactory*)&This->lpVtbl;
+    Filter = (IKsFilterFactory*)&This->Header.OuterUnknown;
 
     /* initialize filter */
     Status = Filter->lpVtbl->Initialize(Filter, DeviceObject, Descriptor, RefString, SecurityDescriptor, CreateItemFlags, SleepCallback, WakeCallback, FilterFactory);
@@ -411,7 +427,7 @@ KsFilterFactorySetDeviceClassesState(
     IKsFilterFactory * Factory;
     IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(FilterFactory, IKsFilterFactoryImpl, FilterFactory);
 
-    Factory = (IKsFilterFactory*)&This->lpVtbl;
+    Factory = (IKsFilterFactory*)&This->Header.OuterUnknown;
     return Factory->lpVtbl->SetDeviceClassesState(Factory, NewState);
 }
 
@@ -468,19 +484,261 @@ KsFilterFactoryAddCreateItem(
     return KsAllocateObjectCreateItem((KSDEVICE_HEADER)Factory->DeviceHeader, &CreateItem, TRUE, IKsFilterFactory_ItemFreeCb);
 }
 
+ULONG
+KspCacheAddData(
+    PKSPCACHE_DESCRIPTOR Descriptor,
+    LPCVOID Data,
+    ULONG Length)
+{
+    ULONG Index;
+
+    for(Index = 0; Index < Descriptor->DataOffset; Index++)
+    {
+        if (RtlCompareMemory(Descriptor->DataCache, Data, Length) == Length)
+        {
+            if (Index + Length > Descriptor->DataOffset)
+            {
+                /* adjust used space */
+                Descriptor->DataOffset = Index + Length;
+                /* return absolute offset */
+                return Descriptor->DataLength + Index;
+            }
+        }
+    }
+
+    /* sanity check */
+    ASSERT(Descriptor->DataOffset + Length < Descriptor->DataLength);
+
+    /* copy to data blob */
+    RtlMoveMemory((Descriptor->DataCache + Descriptor->DataOffset), Data, Length);
+
+    /* backup offset */
+    Index = Descriptor->DataOffset;
+
+    /* adjust used space */
+    Descriptor->DataOffset += Length;
+
+    /* return absolute offset */
+    return Descriptor->DataLength + Index;
+}
+
 /*
     @implemented
 */
 KSDDKAPI
 NTSTATUS
 NTAPI
-KsFilterFactoryUpdateCacheData (
+KsFilterFactoryUpdateCacheData(
     IN PKSFILTERFACTORY  FilterFactory,
     IN const KSFILTER_DESCRIPTOR*  FilterDescriptor OPTIONAL)
 {
-    UNIMPLEMENTED
+    KSPCACHE_DESCRIPTOR Descriptor;
+    PKSPCACHE_FILTER_HEADER FilterHeader;
+    UNICODE_STRING FilterData = RTL_CONSTANT_STRING(L"FilterData");
+    PKSPCACHE_PIN_HEADER PinHeader;
+    ULONG Index, SubIndex;
+    PLIST_ENTRY Entry;
+    PSYMBOLIC_LINK_ENTRY SymEntry;
+    BOOLEAN Found;
+    HKEY hKey;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    IKsFilterFactoryImpl * Factory = (IKsFilterFactoryImpl*)CONTAINING_RECORD(FilterFactory, IKsFilterFactoryImpl, FilterFactory);
+
     DPRINT("KsFilterFactoryUpdateCacheData %p\n", FilterDescriptor);
 
-    return STATUS_SUCCESS;
+    if (!FilterDescriptor)
+        FilterDescriptor = Factory->FilterFactory.FilterDescriptor;
+
+    ASSERT(FilterDescriptor);
+
+    /* initialize cache descriptor */
+    RtlZeroMemory(&Descriptor, sizeof(KSPCACHE_DESCRIPTOR));
+
+    /* calculate filter data size */
+    Descriptor.FilterLength = sizeof(KSPCACHE_FILTER_HEADER);
+
+    /* FIXME support variable size pin descriptors */
+    ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
+
+    for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++)
+    {
+        /* add filter descriptor */
+        Descriptor.FilterLength += sizeof(KSPCACHE_PIN_HEADER);
+
+        if (FilterDescriptor->PinDescriptors[Index].PinDescriptor.Category)
+        {
+            /* add extra ULONG for offset to category */
+            Descriptor.FilterLength += sizeof(ULONG);
+
+            /* add size for clsid */
+            Descriptor.DataLength += sizeof(CLSID);
+        }
+
+        /* add space for formats */
+        Descriptor.FilterLength += FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRangesCount * sizeof(KSPCACHE_DATARANGE);
+
+        /* add space for MajorFormat / MinorFormat */
+        Descriptor.DataLength += FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRangesCount * sizeof(CLSID) * 2;
+
+        /* add space for mediums */
+        Descriptor.FilterLength += FilterDescriptor->PinDescriptors[Index].PinDescriptor.MediumsCount * sizeof(ULONG);
+
+        /* add space for the data */
+        Descriptor.DataLength += FilterDescriptor->PinDescriptors[Index].PinDescriptor.MediumsCount * sizeof(KSPCACHE_MEDIUM);
+    }
+
+    /* now allocate the space */
+    Descriptor.FilterData = (PUCHAR)AllocateItem(NonPagedPool, Descriptor.DataLength + Descriptor.FilterLength);
+    if (!Descriptor.FilterData)
+    {
+        /* no memory */
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* initialize data cache */
+    Descriptor.DataCache = (PUCHAR)((ULONG_PTR)Descriptor.FilterData + Descriptor.FilterLength);
+
+    /* setup filter header */
+    FilterHeader = (PKSPCACHE_FILTER_HEADER)Descriptor.FilterData;
+
+    FilterHeader->dwVersion = 2;
+    FilterHeader->dwMerit = MERIT_DO_NOT_USE;
+    FilterHeader->dwUnused = 0;
+    FilterHeader->dwPins = FilterDescriptor->PinDescriptorsCount;
+
+    Descriptor.FilterOffset = sizeof(KSPCACHE_FILTER_HEADER);
+
+    /* write pin headers */
+    for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++)
+    {
+        /* get offset to pin */
+        PinHeader = (PKSPCACHE_PIN_HEADER)((ULONG_PTR)Descriptor.FilterData + Descriptor.FilterOffset);
+
+        /* write pin header */
+        PinHeader->Signature = 0x33697030 + Index;
+        PinHeader->Flags = 0;
+        PinHeader->Instances = FilterDescriptor->PinDescriptors[Index].InstancesPossible;
+        if (PinHeader->Instances > 1)
+            PinHeader->Flags |= REG_PINFLAG_B_MANY;
+
+
+        PinHeader->MediaTypes = FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRangesCount;
+        PinHeader->Mediums = FilterDescriptor->PinDescriptors[Index].PinDescriptor.MediumsCount;
+        PinHeader->Category = (FilterDescriptor->PinDescriptors[Index].PinDescriptor.Category ? TRUE : FALSE);
+
+        Descriptor.FilterOffset += sizeof(KSPCACHE_PIN_HEADER);
+
+        if (PinHeader->Category)
+        {
+            /* get category offset */
+            PULONG Category = (PULONG)(PinHeader + 1);
+
+            /* write category offset */
+            *Category = KspCacheAddData(&Descriptor, FilterDescriptor->PinDescriptors[Index].PinDescriptor.Category, sizeof(CLSID));
+
+            /* adjust offset */
+            Descriptor.FilterOffset += sizeof(ULONG);
+        }
+
+        /* add dataranges */
+        for(SubIndex = 0; SubIndex < FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRangesCount; SubIndex++)
+        {
+            /* get datarange offset */
+            PKSPCACHE_DATARANGE DataRange = (PKSPCACHE_DATARANGE)((ULONG_PTR)Descriptor.FilterData + Descriptor.FilterOffset);
+
+            /* initialize data range */
+            DataRange->Signature = 0x33797430 + SubIndex;
+            DataRange->dwUnused = 0;
+            DataRange->OffsetMajor = KspCacheAddData(&Descriptor, &FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRanges[SubIndex]->MajorFormat, sizeof(CLSID));
+            DataRange->OffsetMinor = KspCacheAddData(&Descriptor, &FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRanges[SubIndex]->SubFormat, sizeof(CLSID));
+
+            /* adjust offset */
+            Descriptor.FilterOffset += sizeof(KSPCACHE_DATARANGE);
+        }
+
+        /* add mediums */
+        for(SubIndex = 0; SubIndex < FilterDescriptor->PinDescriptors[Index].PinDescriptor.MediumsCount; SubIndex++)
+        {
+            KSPCACHE_MEDIUM Medium;
+            PULONG MediumOffset;
+
+            /* get pin medium offset */
+            MediumOffset = (PULONG)((ULONG_PTR)Descriptor.FilterData + Descriptor.FilterOffset);
+
+            /* copy medium guid */
+            RtlMoveMemory(&Medium.Medium, &FilterDescriptor->PinDescriptors[Index].PinDescriptor.Mediums[SubIndex].Set, sizeof(GUID));
+            Medium.dw1 = FilterDescriptor->PinDescriptors[Index].PinDescriptor.Mediums[SubIndex].Id; /* FIXME verify */
+            Medium.dw2 = 0;
+
+            *MediumOffset = KspCacheAddData(&Descriptor, &Medium, sizeof(KSPCACHE_MEDIUM));
+
+            /* adjust offset */
+            Descriptor.FilterOffset += sizeof(ULONG);
+        }
+    }
+
+    /* sanity checks */
+    ASSERT(Descriptor.FilterOffset == Descriptor.FilterLength);
+    ASSERT(Descriptor.DataOffset <= Descriptor.DataLength);
+
+
+    /* now go through all entries and update 'FilterData' key */
+    for(Index = 0; Index < FilterDescriptor->CategoriesCount; Index++)
+    {
+        /* get first entry */
+        Entry = Factory->SymbolicLinkList.Flink;
+
+        /* set status to not found */
+        Found = FALSE;
+        /* loop list until the the current category is found */
+        while(Entry != &Factory->SymbolicLinkList)
+        {
+            /* fetch symbolic link entry */
+            SymEntry = (PSYMBOLIC_LINK_ENTRY)CONTAINING_RECORD(Entry, SYMBOLIC_LINK_ENTRY, Entry);
+
+            if (IsEqualGUIDAligned(&SymEntry->DeviceInterfaceClass, &FilterDescriptor->Categories[Index]))
+            {
+                /* found category */
+                Found = TRUE;
+                break;
+            }
+
+            /* move to next entry */
+            Entry = Entry->Flink;
+        }
+
+        if (!Found)
+        {
+            /* filter category is not present */
+            Status = STATUS_INVALID_PARAMETER;
+            break;
+        }
+
+        /* now open device interface */
+        Status = IoOpenDeviceInterfaceRegistryKey(&SymEntry->SymbolicLink, KEY_WRITE, &hKey);
+        if (!NT_SUCCESS(Status))
+        {
+            /* failed to open interface key */
+            break;
+        }
+
+        /* update filterdata key */
+        Status = ZwSetValueKey(hKey, &FilterData, 0, REG_BINARY, Descriptor.FilterData, Descriptor.FilterLength + Descriptor.DataOffset);
+
+        /* close filterdata key */
+        ZwClose(hKey);
+
+        if (!NT_SUCCESS(Status))
+        {
+            /* failed to set key value */
+            break;
+        }
+    }
+    /* free filter data */
+    FreeItem(Descriptor.FilterData);
+
+    /* done */
+    return Status;
 }      
 
index e50490a..0c6036e 100644 (file)
@@ -1360,7 +1360,7 @@ KsRemoveIrpFromCancelableQueue(
     PLIST_ENTRY CurEntry;
     KIRQL OldIrql;
 
-    DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
+    //DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
 
     /* check parameters */
     if (!QueueHead || !SpinLock)
@@ -1719,10 +1719,24 @@ FindMatchingCreateItem(
 {
     PLIST_ENTRY Entry;
     PCREATE_ITEM_ENTRY CreateItemEntry;
+    UNICODE_STRING RefString;
 
+
+#ifndef MS_KSUSER
     /* remove '\' slash */
     Buffer++;
     BufferSize -= sizeof(WCHAR);
+#endif
+
+    if (!wcschr(Buffer, L'\\'))
+    {
+        RtlInitUnicodeString(&RefString, Buffer);
+    }
+    else
+    {
+        RefString.Buffer = Buffer;
+        RefString.Length = RefString.MaximumLength = ((ULONG_PTR)wcschr(Buffer, L'\\') - (ULONG_PTR)Buffer);
+    }
 
     /* point to first entry */
     Entry = ListHead->Flink;
@@ -1751,9 +1765,9 @@ FindMatchingCreateItem(
 
         ASSERT(CreateItemEntry->CreateItem->ObjectClass.Buffer);
 
-        DPRINT("CreateItem %S Length %u Request %S %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer,
+        DPRINT("CreateItem %S Length %u Request %wZ %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer,
                                                            CreateItemEntry->CreateItem->ObjectClass.Length,
-                                                           Buffer,
+                                                           &RefString,
                                                            BufferSize);
 
         if (CreateItemEntry->CreateItem->ObjectClass.Length > BufferSize)
@@ -1764,7 +1778,7 @@ FindMatchingCreateItem(
         }
 
          /* now check if the object class is the same */
-        if (RtlCompareMemory(CreateItemEntry->CreateItem->ObjectClass.Buffer, Buffer, CreateItemEntry->CreateItem->ObjectClass.Length) == CreateItemEntry->CreateItem->ObjectClass.Length)
+        if (!RtlCompareUnicodeString(&CreateItemEntry->CreateItem->ObjectClass, &RefString, TRUE))
         {
             /* found matching create item */
             *OutCreateItem = CreateItemEntry;
@@ -1992,7 +2006,7 @@ KsDispatchIrp(
     PKSIDEVICE_HEADER DeviceHeader;
     PDEVICE_EXTENSION DeviceExtension;
 
-    DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
+    //DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
 
     /* get device extension */
     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -2008,7 +2022,7 @@ KsDispatchIrp(
         if (IoStack->MajorFunction == IRP_MJ_CREATE)
         {
             /* check internal type */
-            if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
+            if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
             {
                 /* AVStream client */
                 return IKsDevice_Create(DeviceObject, Irp);
@@ -2040,7 +2054,7 @@ KsDispatchIrp(
     if (IoStack->MajorFunction == IRP_MJ_POWER)
     {
         /* check internal type */
-        if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
+        if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
         {
             /* AVStream client */
             return IKsDevice_Power(DeviceObject, Irp);
@@ -2054,7 +2068,7 @@ KsDispatchIrp(
     else if (IoStack->MajorFunction == IRP_MJ_PNP) /* dispatch pnp */
     {
         /* check internal type */
-        if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
+        if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
         {
             /* AVStream client */
             return IKsDevice_Pnp(DeviceObject, Irp);
index 8d0836a..636c616 100644 (file)
@@ -84,19 +84,17 @@ VOID
 FreeItem(
     IN PVOID Item);
 
-NTSTATUS
-NTAPI
-KspTopologyPropertyHandler(
-    IN PIRP Irp,
-    IN PKSIDENTIFIER  Request,
-    IN OUT PVOID  Data);
-
+KSDDKAPI
 NTSTATUS
 NTAPI
 KspPinPropertyHandler(
-    IN PIRP Irp,
-    IN PKSIDENTIFIER  Request,
-    IN OUT PVOID  Data);
+    IN  PIRP Irp,
+    IN  PKSPROPERTY Property,
+    IN  OUT PVOID Data,
+    IN  ULONG DescriptorsCount,
+    IN  const KSPIN_DESCRIPTOR* Descriptors,
+    IN  ULONG DescriptorSize);
+
 
 NTSTATUS
 FindMatchingCreateItem(
@@ -122,11 +120,6 @@ KspCreatePin(
     IN PKSPIN_CONNECT Connect,
     IN KSPIN_DESCRIPTOR_EX* Descriptor);
 
-NTSTATUS
-IKsFilter_AddPin(
-    IKsFilter * Filter,
-    PKSPIN Pin);
-
 NTSTATUS
 KspAddCreateItemToList(
     OUT PLIST_ENTRY ListHead,
@@ -156,3 +149,40 @@ KspSetFilterFactoriesState(
     IN PKSIDEVICE_HEADER DeviceHeader,
     IN BOOLEAN NewState);
 
+NTSTATUS
+NTAPI
+KspMethodHandlerWithAllocator(
+    IN  PIRP Irp,
+    IN  ULONG MethodSetsCount,
+    IN  const KSMETHOD_SET *MethodSet,
+    IN  PFNKSALLOCATOR Allocator OPTIONAL,
+    IN  ULONG MethodItemSize OPTIONAL);
+
+VOID
+IKsFilter_AddPin(
+    PKSFILTER Filter,
+    PKSPIN Pin);
+
+VOID
+IKsFilter_RemovePin(
+    PKSFILTER Filter,
+    PKSPIN Pin);
+
+NTSTATUS
+KspEnableEvent(
+    IN  PIRP Irp,
+    IN  ULONG EventSetsCount,
+    IN  PKSEVENT_SET EventSet,
+    IN  OUT PLIST_ENTRY EventsList OPTIONAL,
+    IN  KSEVENTS_LOCKTYPE EventsFlags OPTIONAL,
+    IN  PVOID EventsLock OPTIONAL,
+    IN  PFNKSALLOCATOR Allocator OPTIONAL,
+    IN  ULONG EventItemSize OPTIONAL);
+
+NTSTATUS
+KspValidateConnectRequest(
+    IN PIRP Irp,
+    IN ULONG DescriptorsCount,
+    IN PVOID Descriptors,
+    IN ULONG DescriptorSize,
+    OUT PKSPIN_CONNECT* Connect);
index ffea3ed..ad95fc9 100644 (file)
@@ -282,9 +282,9 @@ DECLARE_INTERFACE_(IKsDevice, IUnknown)
     STDMETHOD_(NTSTATUS,ReleaseDevice)(THIS) PURE;
 
     STDMETHOD_(NTSTATUS, GetAdapterObject)(THIS_
-        IN PADAPTER_OBJECT Object,
-        IN PULONG Unknown1,
-        IN PULONG Unknown2) PURE;
+        IN PADAPTER_OBJECT Object,
+        IN PULONG MaxMappingsByteCount,
+        IN PULONG MappingTableStride) PURE;
 
     STDMETHOD_(NTSTATUS, AddPowerEntry)(THIS_
         IN struct KSPOWER_ENTRY * Entry,
@@ -300,8 +300,8 @@ DECLARE_INTERFACE_(IKsDevice, IUnknown)
         IN KSSTATE NewState)PURE;
 
     STDMETHOD_(NTSTATUS, ArbitrateAdapterChannel)(THIS_
-        IN ULONG ControlCode,
-        IN IO_ALLOCATION_ACTION Action,
+        IN ULONG NumberOfMapRegisters,
+        IN PDRIVER_CONTROL ExecutionRoutine,
         IN PVOID Context)PURE;
 
     STDMETHOD_(NTSTATUS, CheckIoCapability)(THIS_
index 4bdc04c..0e64312 100644 (file)
@@ -58,9 +58,11 @@ typedef struct
 {
     KSOBJECTTYPE Type;
     PKSDEVICE KsDevice;
-    KMUTEX ControlMutex;
+    PRKMUTEX ControlMutex;
     LIST_ENTRY EventList;
     KSPIN_LOCK EventListLock;
+    PUNKNOWN ClientAggregate;
+    PUNKNOWN OuterUnknown;
     union
     {
         PKSDEVICE KsDevice;
@@ -87,7 +89,6 @@ typedef struct
 {
     KSBASIC_HEADER BasicHeader;
     KSDEVICE KsDevice;
-    IKsDeviceVtbl *lpVtblIKsDevice;
 
     LONG ref;
     ERESOURCE SecurityLock;
@@ -108,6 +109,10 @@ typedef struct
     LIST_ENTRY PowerDispatchList;
     LIST_ENTRY ObjectBags;
 
+    PADAPTER_OBJECT AdapterObject;
+    ULONG MaxMappingsByteCount;
+    ULONG MappingTableStride;
+
 }KSIDEVICE_HEADER, *PKSIDEVICE_HEADER;
 
 typedef struct
@@ -120,6 +125,7 @@ typedef struct
 {
     LIST_ENTRY Entry;
     UNICODE_STRING SymbolicLink;
+    CLSID DeviceInterfaceClass;
 }SYMBOLIC_LINK_ENTRY, *PSYMBOLIC_LINK_ENTRY;
 
 typedef struct
@@ -157,3 +163,51 @@ typedef struct
 
     WCHAR BusIdentifier[1];
 }BUS_ENUM_DEVICE_EXTENSION, *PBUS_ENUM_DEVICE_EXTENSION;
+
+typedef struct
+{
+    PUCHAR FilterData;
+    ULONG FilterLength;
+    ULONG FilterOffset;
+
+    PUCHAR DataCache;
+    ULONG DataLength;
+    ULONG DataOffset;
+
+}KSPCACHE_DESCRIPTOR, *PKSPCACHE_DESCRIPTOR;
+
+typedef struct
+{
+    DWORD dwVersion;
+    DWORD dwMerit;
+    DWORD dwPins;
+    DWORD dwUnused;
+}KSPCACHE_FILTER_HEADER, *PKSPCACHE_FILTER_HEADER;
+
+typedef struct
+{
+    ULONG Signature;
+    ULONG Flags;
+    ULONG Instances;
+    ULONG MediaTypes;
+    ULONG Mediums;
+    DWORD Category;
+}KSPCACHE_PIN_HEADER, *PKSPCACHE_PIN_HEADER;
+
+
+typedef struct
+{
+    ULONG Signature;
+    ULONG dwUnused;
+    ULONG OffsetMajor;
+    ULONG OffsetMinor;
+}KSPCACHE_DATARANGE, *PKSPCACHE_DATARANGE;
+
+
+typedef struct
+{
+    CLSID Medium;
+    ULONG dw1;
+    ULONG dw2;
+}KSPCACHE_MEDIUM;
+
index 512371a..6263ce0 100644 (file)
@@ -8,8 +8,183 @@
 
 #include "priv.h"
 
+NTSTATUS
+FindMethodHandler(
+    IN PIO_STATUS_BLOCK IoStatus,
+    IN  const KSMETHOD_SET* MethodSet,
+    IN ULONG MethodSetCount,
+    IN PKSMETHOD Method,
+    IN ULONG InputBufferLength,
+    IN ULONG OutputBufferLength,
+    OUT PVOID OutputBuffer,
+    OUT PFNKSHANDLER *MethodHandler,
+    OUT PKSMETHOD_SET * Set)
+{
+    ULONG Index, ItemIndex;
+
+    for(Index = 0; Index < MethodSetCount; Index++)
+    {
+        ASSERT(MethodSet[Index].Set);
+
+        if (IsEqualGUIDAligned(&Method->Set, MethodSet[Index].Set))
+        {
+            for(ItemIndex = 0; ItemIndex < MethodSet[Index].MethodsCount; ItemIndex++)
+            {
+                if (MethodSet[Index].MethodItem[ItemIndex].MethodId == Method->Id)
+                {
+                    if (MethodSet[Index].MethodItem[ItemIndex].MinMethod > InputBufferLength)
+                    {
+                        /* too small input buffer */
+                        IoStatus->Information = MethodSet[Index].MethodItem[ItemIndex].MinMethod;
+                        return STATUS_INVALID_PARAMETER;
+                    }
+
+                    if (MethodSet[Index].MethodItem[ItemIndex].MinData > OutputBufferLength)
+                    {
+                        /* too small output buffer */
+                        IoStatus->Information = MethodSet[Index].MethodItem[ItemIndex].MinData;
+                        return STATUS_MORE_ENTRIES;
+                    }
+                    if (Method->Flags & KSMETHOD_TYPE_BASICSUPPORT)
+                    {
+                        PULONG Flags;
+                        PKSPROPERTY_DESCRIPTION Description;
+
+                        if (sizeof(ULONG) > OutputBufferLength)
+                        {
+                            /* too small buffer */
+                            return STATUS_INVALID_PARAMETER;
+                        }
+
+                        /* get output buffer */
+                        Flags = (PULONG)OutputBuffer;
+
+                        /* set flags flags */
+                        *Flags = MethodSet[Index].MethodItem[ItemIndex].Flags;
+
+                        IoStatus->Information = sizeof(ULONG);
+
+                        if (OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION))
+                        {
+                            /* get output buffer */
+                            Description = (PKSPROPERTY_DESCRIPTION)OutputBuffer;
+
+                            /* store result */
+                            Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION);
+                            Description->PropTypeSet.Set = KSPROPTYPESETID_General;
+                            Description->PropTypeSet.Id = 0;
+                            Description->PropTypeSet.Flags = 0;
+                            Description->MembersListCount = 0;
+                            Description->Reserved = 0;
+
+                            IoStatus->Information = sizeof(KSPROPERTY_DESCRIPTION);
+                        }
+                        return STATUS_SUCCESS;
+                    }
+                    *MethodHandler = MethodSet[Index].MethodItem[ItemIndex].MethodHandler;
+                    *Set = (PKSMETHOD_SET)&MethodSet[Index];
+                    return STATUS_SUCCESS;
+                }
+            }
+        }
+    }
+    return STATUS_NOT_FOUND;
+}
+
+NTSTATUS
+NTAPI
+KspMethodHandlerWithAllocator(
+    IN  PIRP Irp,
+    IN  ULONG MethodSetsCount,
+    IN  const KSMETHOD_SET *MethodSet,
+    IN  PFNKSALLOCATOR Allocator OPTIONAL,
+    IN  ULONG MethodItemSize OPTIONAL)
+{
+    PKSMETHOD Method;
+    PKSMETHOD_SET Set;
+    PIO_STACK_LOCATION IoStack;
+    NTSTATUS Status;
+    PFNKSHANDLER MethodHandler = NULL;
+    ULONG Index;
+    LPGUID Guid;
+
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* check if inputbuffer at least holds KSMETHOD item */
+    if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSMETHOD))
+    {
+        /* invalid parameter */
+        Irp->IoStatus.Information = sizeof(KSPROPERTY);
+        return STATUS_INVALID_BUFFER_SIZE;
+    }
+
+    /* FIXME probe the input / output buffer if from user mode */
+
+    /* get input property request */
+    Method = (PKSMETHOD)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+//    DPRINT("KspMethodHandlerWithAllocator Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM));
+
+    /* sanity check */
+    ASSERT(MethodItemSize == 0 || MethodItemSize == sizeof(KSMETHOD_ITEM));
+
+    /* find the method handler */
+    Status = FindMethodHandler(&Irp->IoStatus, MethodSet, MethodSetsCount, Method, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Irp->UserBuffer, &MethodHandler, &Set);
+
+    if (NT_SUCCESS(Status) && MethodHandler)
+    {
+        /* call method handler */
+        KSMETHOD_SET_IRP_STORAGE(Irp) = Set;
+        Status = MethodHandler(Irp, Method, Irp->UserBuffer);
+
+        if (Status == STATUS_BUFFER_TOO_SMALL)
+        {
+            /* output buffer is too small */
+            if (Allocator)
+            {
+                /* allocate the requested amount */
+                Status = Allocator(Irp, Irp->IoStatus.Information, FALSE);
+
+                /* check if the block was allocated */
+                if (!NT_SUCCESS(Status))
+                {
+                    /* no memory */
+                    return STATUS_INSUFFICIENT_RESOURCES;
+                }
+
+                /* re-call method handler */
+                Status = MethodHandler(Irp, Method, Irp->UserBuffer);
+            }
+        }
+    }
+    else if (IsEqualGUIDAligned(&Method->Set, &GUID_NULL) && Method->Id == 0 && Method->Flags == KSMETHOD_TYPE_SETSUPPORT)
+    {
+        // store output size
+        Irp->IoStatus.Information = sizeof(GUID) * MethodSetsCount;
+        if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * MethodSetsCount)
+        {
+            // buffer too small
+            return STATUS_MORE_ENTRIES;
+        }
+
+        // get output buffer
+        Guid = (LPGUID)Irp->UserBuffer;
+
+       // copy property guids from property sets
+       for(Index = 0; Index < MethodSetsCount; Index++)
+       {
+           RtlMoveMemory(&Guid[Index], MethodSet[Index].Set, sizeof(GUID));
+       }
+       return STATUS_SUCCESS;
+    }
+
+    /* done */
+    return Status;
+}
+
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 NTSTATUS
@@ -19,12 +194,11 @@ KsMethodHandler(
     IN  ULONG MethodSetsCount,
     IN  PKSMETHOD_SET MethodSet)
 {
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;
+    return KspMethodHandlerWithAllocator(Irp, MethodSetsCount, MethodSet, NULL, 0);
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 NTSTATUS
@@ -36,12 +210,39 @@ KsMethodHandlerWithAllocator(
     IN  PFNKSALLOCATOR Allocator OPTIONAL,
     IN  ULONG MethodItemSize OPTIONAL)
 {
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;
+    return KspMethodHandlerWithAllocator(Irp, MethodSetsCount, MethodSet, Allocator, MethodItemSize);
 }
 
+
+NTSTATUS
+FindFastMethodHandler(
+    IN ULONG FastIoCount,
+    IN const KSFASTMETHOD_ITEM * FastIoTable,
+    IN PKSMETHOD MethodId,
+    OUT PFNKSFASTHANDLER * FastPropertyHandler)
+{
+    ULONG Index;
+
+    /* iterate through all items */
+    for(Index = 0; Index < FastIoCount; Index++)
+    {
+        if (MethodId->Id == FastIoTable[Index].MethodId)
+        {
+            if (FastIoTable[Index].MethodSupported)
+            {
+                *FastPropertyHandler = FastIoTable[Index].MethodHandler;
+                return STATUS_SUCCESS;
+            }
+        }
+
+    }
+    /* no fast property handler found */
+    return STATUS_NOT_FOUND;
+}
+
+
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 BOOLEAN
@@ -56,6 +257,68 @@ KsFastMethodHandler(
     IN  ULONG MethodSetsCount,
     IN  const KSMETHOD_SET* MethodSet)
 {
-    UNIMPLEMENTED;
+    KSMETHOD MethodRequest;
+    KPROCESSOR_MODE Mode;
+    NTSTATUS Status = STATUS_SUCCESS;
+    ULONG Index;
+    PFNKSFASTHANDLER FastMethodHandler;
+
+    if (MethodLength < sizeof(KSPROPERTY))
+    {
+        /* invalid request */
+        return FALSE;
+    }
+
+    /* get previous mode */
+    Mode = ExGetPreviousMode();
+
+    if (Mode == KernelMode)
+    {
+        /* just copy it */
+        RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD));
+    }
+    else
+    {
+        /* need to probe the buffer */
+        _SEH2_TRY
+        {
+            ProbeForRead(Method, sizeof(KSPROPERTY), sizeof(UCHAR));
+            RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD));
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Exception, get the error code */
+            Status = _SEH2_GetExceptionCode();
+        }_SEH2_END;
+
+        if (!NT_SUCCESS(Status))
+            return FALSE;
+    }
+
+    /* are there any property sets provided */
+    if (MethodSetsCount)
+    {
+        /* iterate through all property sets count */
+        Index = 0;
+        do
+        {
+            /* does the property id match */
+            if (IsEqualGUIDAligned(MethodSet[Index].Set, &MethodRequest.Set))
+            {
+                /* try to find a fast property handler */
+                Status = FindFastMethodHandler(MethodSet[Index].FastIoCount, MethodSet[Index].FastIoTable, &MethodRequest, &FastMethodHandler);
+
+                if (NT_SUCCESS(Status))
+                {
+                    /* call fast property handler */
+                    ASSERT(MethodLength == sizeof(KSMETHOD)); /* FIXME check if property length is bigger -> copy params */
+                    ASSERT(Mode == KernelMode); /* FIXME need to probe usermode output buffer */
+                    return FastMethodHandler(FileObject, &MethodRequest, sizeof(KSMETHOD), Data, DataLength, IoStatus);
+                }
+            }
+            /* move to next item */
+            Index++;
+        }while(Index < MethodSetsCount);
+    }
     return FALSE;
 }
index cc3d2cc..dc814ea 100644 (file)
@@ -175,16 +175,21 @@ KsGetObjectTypeFromIrp(
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 PUNKNOWN
 NTAPI
 KsGetOuterUnknown(
     IN PVOID  Object)
 {
-    UNIMPLEMENTED
-    return NULL;
+    PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
+
+    /* sanity check */
+    ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || 
+           BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
 
+    /* return objects outer unknown */
+    return BasicHeader->OuterUnknown;
 }
 
 /*
index 5d1ee77..019e5ce 100644 (file)
 
 typedef struct _KSISTREAM_POINTER
 {
-    KSSTREAM_POINTER StreamPointer;
     PFNKSSTREAMPOINTER Callback;
     PIRP Irp;
     KTIMER Timer;
     KDPC TimerDpc;
     struct _KSISTREAM_POINTER *Next;
-
+    PKSPIN Pin;
+    PVOID Data;
+    ULONG Offset;
+    ULONG Length;
+    KSSTREAM_POINTER StreamPointer;
+    KSPIN_LOCK Lock;
 }KSISTREAM_POINTER, *PKSISTREAM_POINTER;
 
 typedef struct
@@ -28,9 +32,9 @@ typedef struct
     KSPROCESSPIN ProcessPin;
     LIST_ENTRY Entry;
 
-    IKsPinVtbl *lpVtbl;
-
     LONG ref;
+
+    IKsFilter * Filter;
     KMUTEX ProcessingMutex;
     PFILE_OBJECT FileObject;
 
@@ -39,10 +43,11 @@ typedef struct
 
     LIST_ENTRY IrpList;
     KSPIN_LOCK IrpListLock;
+    volatile LONG IrpCount;
 
     PKSISTREAM_POINTER ClonedStreamPointer;
-    PKSISTREAM_POINTER LeadingEdgeStreamPointer;
-    PKSISTREAM_POINTER TrailingStreamPointer;
+    KSISTREAM_POINTER LeadingEdgeStreamPointer;
+    KSISTREAM_POINTER TrailingStreamPointer;
 
     PFNKSPINPOWER  Sleep;
     PFNKSPINPOWER  Wake;
@@ -50,8 +55,425 @@ typedef struct
     PFNKSPINFRAMERETURN  FrameReturn;
     PFNKSPINIRPCOMPLETION  IrpCompletion;
 
+    KSCLOCK_FUNCTIONTABLE ClockTable;
+    PFILE_OBJECT ClockFileObject;
+    IKsReferenceClockVtbl * lpVtblReferenceClock;
+    PKSDEFAULTCLOCK DefaultClock;
+
+    PKSWORKER PinWorker;
+    WORK_QUEUE_ITEM PinWorkQueueItem;
+    KEVENT FrameComplete;
+    ULONG FrameSize;
+    ULONG NumFrames;
+    PDMA_ADAPTER Dma;
+    ULONG MapRegisters;
+
 }IKsPinImpl;
 
+NTSTATUS NTAPI IKsPin_PinStatePropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinDataFormatPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinAllocatorFramingPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinStreamAllocator(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinMasterClock(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinPipeId(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+
+
+
+DEFINE_KSPROPERTY_CONNECTIONSET(PinConnectionSet, IKsPin_PinStatePropertyHandler, IKsPin_PinDataFormatPropertyHandler, IKsPin_PinAllocatorFramingPropertyHandler);
+DEFINE_KSPROPERTY_STREAMSET(PinStreamSet, IKsPin_PinStreamAllocator, IKsPin_PinMasterClock, IKsPin_PinPipeId);
+
+//TODO
+// KSPROPSETID_Connection
+//    KSPROPERTY_CONNECTION_ACQUIREORDERING
+// KSPROPSETID_StreamInterface
+//     KSPROPERTY_STREAMINTERFACE_HEADERSIZE
+
+KSPROPERTY_SET PinPropertySet[] =
+{
+    {
+        &KSPROPSETID_Connection,
+        sizeof(PinConnectionSet) / sizeof(KSPROPERTY_ITEM),
+        (const KSPROPERTY_ITEM*)&PinConnectionSet,
+        0,
+        NULL
+    },
+    {
+        &KSPROPSETID_Stream,
+        sizeof(PinStreamSet) / sizeof(KSPROPERTY_ITEM),
+        (const KSPROPERTY_ITEM*)&PinStreamSet,
+        0,
+        NULL
+    }
+};
+
+const GUID KSPROPSETID_Connection              = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+const GUID KSPROPSETID_Stream                  = {0x65aaba60L, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
+const GUID KSPROPSETID_Clock                   = {0xDF12A4C0L, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+
+NTSTATUS
+NTAPI
+IKsPin_PinStreamAllocator(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    UNIMPLEMENTED
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+IKsPin_PinMasterClock(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PIO_STACK_LOCATION IoStack;
+    PKSIOBJECT_HEADER ObjectHeader;
+    IKsPinImpl * This;
+    NTSTATUS Status = STATUS_SUCCESS;
+    PHANDLE Handle;
+    PFILE_OBJECT FileObject;
+    KPROCESSOR_MODE Mode;
+    KSPROPERTY Property;
+    ULONG BytesReturned;
+
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("IKsPin_PinMasterClock\n");
+
+    /* sanity check */
+    ASSERT(IoStack->FileObject);
+    ASSERT(IoStack->FileObject->FsContext2);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* sanity check */
+    ASSERT(ObjectHeader);
+
+    /* locate ks pin implemention from KSPIN offset */
+    This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
+
+    /* sanity check */
+    ASSERT(This);
+
+    Handle = (PHANDLE)Data;
+
+    if (Request->Flags & KSPROPERTY_TYPE_GET)
+    {
+        if (This->Pin.Descriptor->PinDescriptor.Communication != KSPIN_COMMUNICATION_NONE &&
+            This->Pin.Descriptor->Dispatch &&
+            (This->Pin.Descriptor->Flags & KSPIN_FLAG_IMPLEMENT_CLOCK))
+        {
+            *Handle = NULL;
+            Status = STATUS_SUCCESS;
+        }
+        else
+        {
+            /* no clock available */
+            Status = STATUS_UNSUCCESSFUL;
+        }
+    }
+    else if (Request->Flags & KSPROPERTY_TYPE_SET)
+    {
+        if (This->Pin.ClientState != KSSTATE_STOP)
+        {
+            /* can only set in stopped state */
+            Status = STATUS_INVALID_DEVICE_STATE;
+        }
+        else
+        {
+            if (*Handle)
+            {
+                Mode = ExGetPreviousMode();
+
+                Status = ObReferenceObjectByHandle(*Handle, SYNCHRONIZE | DIRECTORY_QUERY, IoFileObjectType, Mode, (PVOID*)&FileObject, NULL);
+
+                DPRINT("IKsPin_PinMasterClock ObReferenceObjectByHandle %lx\n", Status);
+                if (NT_SUCCESS(Status))
+                {
+                    Property.Set = KSPROPSETID_Clock;
+                    Property.Id = KSPROPERTY_CLOCK_FUNCTIONTABLE;
+                    Property.Flags = KSPROPERTY_TYPE_GET;
+
+                    Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), &This->ClockTable, sizeof(KSCLOCK_FUNCTIONTABLE), &BytesReturned);
+
+                    DPRINT("IKsPin_PinMasterClock KSPROPERTY_CLOCK_FUNCTIONTABLE %lx\n", Status);
+
+                    if (NT_SUCCESS(Status))
+                    {
+                        This->ClockFileObject = FileObject;
+                    }
+                    else
+                    {
+                        ObDereferenceObject(FileObject);
+                    }
+                }
+            }
+            else
+            {
+                /* zeroing clock handle */
+                RtlZeroMemory(&This->ClockTable, sizeof(KSCLOCK_FUNCTIONTABLE));
+                Status = STATUS_SUCCESS;
+                if (This->ClockFileObject)
+                {
+                    FileObject = This->ClockFileObject;
+                    This->ClockFileObject = NULL;
+
+                    ObDereferenceObject(This->ClockFileObject);
+                }
+            }
+        }
+    }
+
+    DPRINT("IKsPin_PinMasterClock Status %lx\n", Status);
+    return Status;
+}
+
+
+
+NTSTATUS
+NTAPI
+IKsPin_PinPipeId(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    UNIMPLEMENTED
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS
+NTAPI
+IKsPin_PinStatePropertyHandler(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PIO_STACK_LOCATION IoStack;
+    PKSIOBJECT_HEADER ObjectHeader;
+    IKsPinImpl * This;
+    NTSTATUS Status = STATUS_SUCCESS;
+    KSSTATE OldState;
+    PKSSTATE NewState;
+
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("IKsPin_PinStatePropertyHandler\n");
+
+    /* sanity check */
+    ASSERT(IoStack->FileObject);
+    ASSERT(IoStack->FileObject->FsContext2);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* locate ks pin implemention from KSPIN offset */
+    This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
+
+    /* acquire control mutex */
+    KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL);
+
+    /* grab state */
+    NewState = (PKSSTATE)Data;
+
+    if (Request->Flags & KSPROPERTY_TYPE_GET)
+    {
+        *NewState = This->Pin.DeviceState;
+        Irp->IoStatus.Information = sizeof(KSSTATE);
+    }
+    else if (Request->Flags & KSPROPERTY_TYPE_SET)
+    {
+        if (This->Pin.Descriptor->Dispatch->SetDeviceState)
+        {
+            /* backup old state */
+            OldState = This->Pin.ClientState;
+
+            /* set new state */
+            This->Pin.ClientState  = *NewState;
+            This->Pin.DeviceState = KSSTATE_RUN;
+
+            /* check if it supported */
+            Status = This->Pin.Descriptor->Dispatch->SetDeviceState(&This->Pin, *NewState, OldState);
+
+            DPRINT("IKsPin_PinStatePropertyHandler NewState %lu Result %lx\n", *NewState, Status);
+
+            if (!NT_SUCCESS(Status))
+            {
+                /* revert to old state */
+                This->Pin.ClientState = OldState;
+                This->Pin.DeviceState = OldState;
+                DPRINT("IKsPin_PinStatePropertyHandler failed to set state %lx Result %lx\n", *NewState, Status);
+                DbgBreakPoint();
+            }
+            else
+            {
+                /* update device state */
+                This->Pin.DeviceState = *NewState;
+            }
+        }
+        else
+        {
+            /* just set new state */
+            This->Pin.DeviceState = *NewState;
+            This->Pin.ClientState = *NewState;
+        }
+    }
+
+    /* release processing mutex */
+    KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
+
+    DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+IKsPin_PinAllocatorFramingPropertyHandler(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PIO_STACK_LOCATION IoStack;
+    PKSIOBJECT_HEADER ObjectHeader;
+    IKsPinImpl * This;
+    ULONG Size;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* sanity check */
+    ASSERT(IoStack->FileObject);
+    ASSERT(IoStack->FileObject->FsContext2);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* locate ks pin implemention from KSPIN offset */
+    This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
+
+    /* setting allocator flags is not supported */
+    ASSERT(!(Request->Flags & KSPROPERTY_TYPE_SET));
+
+    /* acquire control mutex */
+    KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL);
+
+    if (This->Pin.Descriptor->AllocatorFraming)
+    {
+        /* calculate size */
+        Size = FIELD_OFFSET(KSALLOCATOR_FRAMING_EX, FramingItem[0]) + This->Pin.Descriptor->AllocatorFraming->CountItems * sizeof(KS_FRAMING_ITEM);
+
+        if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
+        {
+            /* no buffer */
+            Status = STATUS_BUFFER_OVERFLOW;
+        }
+        else if (Size > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
+        {
+            /* buffer too small */
+            Status = STATUS_BUFFER_TOO_SMALL;
+        }
+        else
+        {
+            /* copy buffer */
+            RtlMoveMemory(Data, This->Pin.Descriptor->AllocatorFraming, Size);
+        }
+
+        /* store size */
+        Irp->IoStatus.Information = Size;
+    }
+    else
+    {
+        /* no allocator framing details */
+        Status = STATUS_NOT_FOUND;
+    }
+
+    /* release processing mutex */
+    KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
+
+    DPRINT("IKsPin_PinAllocatorFramingPropertyHandler Status %lx\n", Status);
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+IKsPin_PinDataFormatPropertyHandler(
+    IN PIRP Irp,
+    IN PKSPROPERTY Request,
+    IN OUT PVOID Data)
+{
+    PIO_STACK_LOCATION IoStack;
+    PKSIOBJECT_HEADER ObjectHeader;
+    IKsPinImpl * This;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("IKsPin_PinDataFormatPropertyHandler\n");
+
+    /* sanity check */
+    ASSERT(IoStack->FileObject);
+    ASSERT(IoStack->FileObject->FsContext2);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* locate ks pin implemention from KSPIN offset */
+    This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
+
+    /* acquire control mutex */
+    KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL);
+
+    if (Request->Flags & KSPROPERTY_TYPE_GET)
+    {
+        if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < This->Pin.ConnectionFormat->FormatSize)
+        {
+            /* buffer too small */
+            Irp->IoStatus.Information = This->Pin.ConnectionFormat->FormatSize;
+            Status = STATUS_BUFFER_TOO_SMALL;
+        }
+        else
+        {
+            /* copy format */
+            RtlMoveMemory(Data, This->Pin.ConnectionFormat, This->Pin.ConnectionFormat->FormatSize);
+        }
+    }
+    else if (Request->Flags & KSPROPERTY_TYPE_SET)
+    {
+        /* set format */
+        if (This->Pin.Descriptor->Flags & KSPIN_FLAG_FIXED_FORMAT)
+        {
+            /* format cannot be changed */
+            Status = STATUS_INVALID_DEVICE_REQUEST;
+        }
+        else
+        {
+            /* FIXME check if the format is supported */
+            Status = _KsEdit(This->Pin.Bag, (PVOID*)&This->Pin.ConnectionFormat, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This->Pin.ConnectionFormat->FormatSize, 0);
+
+            if (NT_SUCCESS(Status))
+            {
+                /* store new format */
+                RtlMoveMemory(This->Pin.ConnectionFormat, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength);
+            }
+        }
+    }
+
+    /* release processing mutex */
+    KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
+
+    DPRINT("IKsPin_PinDataFormatPropertyHandler Status %lx\n", Status);
+
+    return Status;
+}
+
 NTSTATUS
 NTAPI
 IKsPin_fnQueryInterface(
@@ -59,15 +481,31 @@ IKsPin_fnQueryInterface(
     IN  REFIID refiid,
     OUT PVOID* Output)
 {
-    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
+    NTSTATUS Status;
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown);
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
     {
-        *Output = &This->lpVtbl;
+        *Output = &This->BasicHeader.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
-    return STATUS_UNSUCCESSFUL;
+
+
+    if (This->BasicHeader.ClientAggregate)
+    {
+         /* using client aggregate */
+         Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output);
+
+         if (NT_SUCCESS(Status))
+         {
+             /* client aggregate supports interface */
+             return Status;
+         }
+    }
+
+    DPRINT("IKsPin_fnQueryInterface no interface\n");
+    return STATUS_NOT_SUPPORTED;
 }
 
 ULONG
@@ -75,7 +513,7 @@ NTAPI
 IKsPin_fnAddRef(
     IKsPin * iface)
 {
-    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown);
 
     return InterlockedIncrement(&This->ref);
 }
@@ -85,7 +523,7 @@ NTAPI
 IKsPin_fnRelease(
     IKsPin * iface)
 {
-    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl);
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown);
 
     InterlockedDecrement(&This->ref);
 
@@ -270,6 +708,219 @@ static IKsPinVtbl vt_IKsPin =
 
 //==============================================================
 
+NTSTATUS
+NTAPI
+IKsReferenceClock_fnQueryInterface(
+    IKsReferenceClock * iface,
+    IN  REFIID refiid,
+    OUT PVOID* Output)
+{
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    return IKsPin_fnQueryInterface((IKsPin*)&This->BasicHeader.OuterUnknown, refiid, Output);
+}
+
+ULONG
+NTAPI
+IKsReferenceClock_fnAddRef(
+    IKsReferenceClock * iface)
+{
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    return IKsPin_fnAddRef((IKsPin*)&This->BasicHeader.OuterUnknown);
+}
+
+ULONG
+NTAPI
+IKsReferenceClock_fnRelease(
+    IKsReferenceClock * iface)
+{
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    return IKsPin_fnRelease((IKsPin*)&This->BasicHeader.OuterUnknown);
+}
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetTime(
+    IKsReferenceClock * iface)
+{
+    LONGLONG Result;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+
+    DPRINT1("IKsReferenceClock_fnGetTime\n");
+
+    if (!This->ClockFileObject || !This->ClockTable.GetTime)
+    {
+        Result = 0;
+    }
+    else
+    {
+        Result = This->ClockTable.GetTime(This->ClockFileObject);
+    }
+
+    return Result;
+}
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetPhysicalTime(
+    IKsReferenceClock * iface)
+{
+    LONGLONG Result;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    DPRINT1("IKsReferenceClock_fnGetPhysicalTime\n");
+
+
+    if (!This->ClockFileObject || !This->ClockTable.GetPhysicalTime)
+    {
+        Result = 0;
+    }
+    else
+    {
+        Result = This->ClockTable.GetPhysicalTime(This->ClockFileObject);
+    }
+
+    return Result;
+}
+
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetCorrelatedTime(
+    IKsReferenceClock * iface,
+    OUT PLONGLONG SystemTime)
+{
+    LONGLONG Result;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    DPRINT1("IKsReferenceClock_fnGetCorrelatedTime\n");
+
+    if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedTime)
+    {
+        Result = 0;
+    }
+    else
+    {
+        Result = This->ClockTable.GetCorrelatedTime(This->ClockFileObject, SystemTime);
+    }
+
+    return Result;
+}
+
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetCorrelatedPhysicalTime(
+    IKsReferenceClock * iface,
+    OUT PLONGLONG SystemTime)
+{
+    LONGLONG Result;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    DPRINT1("IKsReferenceClock_fnGetCorrelatedPhysicalTime\n");
+
+    if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedPhysicalTime)
+    {
+        Result = 0;
+    }
+    else
+    {
+        Result = This->ClockTable.GetCorrelatedPhysicalTime(This->ClockFileObject, SystemTime);
+    }
+
+    return Result;
+}
+
+NTSTATUS
+NTAPI
+IKsReferenceClock_fnGetResolution(
+    IKsReferenceClock * iface,
+    OUT PKSRESOLUTION Resolution)
+{
+    KSPROPERTY Property;
+    ULONG BytesReturned;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    DPRINT1("IKsReferenceClock_fnGetResolution\n");
+
+    if (!This->ClockFileObject)
+    {
+        Resolution->Error = 0;
+        Resolution->Granularity = 1;
+        DPRINT1("IKsReferenceClock_fnGetResolution Using HACK\n");
+        return STATUS_SUCCESS;
+    }
+
+
+    if (!This->ClockFileObject)
+        return STATUS_DEVICE_NOT_READY;
+
+
+    Property.Set = KSPROPSETID_Clock;
+    Property.Id = KSPROPERTY_CLOCK_RESOLUTION;
+    Property.Flags = KSPROPERTY_TYPE_GET;
+
+    return KsSynchronousIoControlDevice(This->ClockFileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), Resolution, sizeof(KSRESOLUTION), &BytesReturned);
+
+}
+
+NTSTATUS
+NTAPI
+IKsReferenceClock_fnGetState(
+    IKsReferenceClock * iface,
+     OUT PKSSTATE State)
+{
+    KSPROPERTY Property;
+    ULONG BytesReturned;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    DPRINT1("IKsReferenceClock_fnGetState\n");
+
+    if (!This->ClockFileObject)
+    {
+        *State = This->Pin.ClientState;
+        DPRINT1("IKsReferenceClock_fnGetState Using HACK\n");
+        return STATUS_SUCCESS;
+    }
+
+
+    if (!This->ClockFileObject)
+        return STATUS_DEVICE_NOT_READY;
+
+
+    Property.Set = KSPROPSETID_Clock;
+    Property.Id = KSPROPERTY_CLOCK_RESOLUTION;
+    Property.Flags = KSPROPERTY_TYPE_GET;
+
+    return KsSynchronousIoControlDevice(This->ClockFileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), State, sizeof(KSSTATE), &BytesReturned);
+}
+
+static IKsReferenceClockVtbl vt_ReferenceClock =
+{
+    IKsReferenceClock_fnQueryInterface,
+    IKsReferenceClock_fnAddRef,
+    IKsReferenceClock_fnRelease,
+    IKsReferenceClock_fnGetTime,
+    IKsReferenceClock_fnGetPhysicalTime,
+    IKsReferenceClock_fnGetCorrelatedTime,
+    IKsReferenceClock_fnGetCorrelatedPhysicalTime,
+    IKsReferenceClock_fnGetResolution,
+    IKsReferenceClock_fnGetState
+};
+
+
+//==============================================================
+
+
 /*
     @implemented
 */
@@ -340,6 +991,7 @@ KsPinAttemptProcessing(
     IN BOOLEAN  Asynchronous)
 {
     DPRINT("KsPinAttemptProcessing\n");
+    DbgBreakPoint();
     UNIMPLEMENTED
 }
 
@@ -448,17 +1100,26 @@ KsPinGetParentFilter(
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 NTSTATUS
 NTAPI
-  KsPinGetReferenceClockInterface(
+KsPinGetReferenceClockInterface(
     IN PKSPIN  Pin,
     OUT PIKSREFERENCECLOCK*  Interface)
 {
-    UNIMPLEMENTED
-    DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p\n", Pin, Interface);
-    return STATUS_UNSUCCESSFUL;
+    NTSTATUS Status = STATUS_DEVICE_NOT_READY;
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
+
+    if (This->ClockFileObject)
+    {
+        /* clock is available */
+        *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock;
+        Status = STATUS_SUCCESS;
+    }
+
+    DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin, Interface, Status);
+    return Status;
 }
 
 /*
@@ -547,15 +1208,26 @@ KsGetPinFromIrp(
     IN PIRP Irp)
 {
     PKSIOBJECT_HEADER ObjectHeader;
+    PKSPIN Pin;
+    PKSBASIC_HEADER Header;
     PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
 
     DPRINT("KsGetPinFromIrp\n");
 
     /* get object header */
     ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
-    /* return object type */
-    return (PKSPIN)ObjectHeader->ObjectType;
 
+    if (!ObjectHeader)
+        return NULL;
+
+    Pin = (PKSPIN)ObjectHeader->ObjectType;
+    Header = (PKSBASIC_HEADER)((ULONG_PTR)Pin - sizeof(KSBASIC_HEADER));
+
+    /* sanity check */
+    ASSERT(Header->Type == KsObjectTypePin);
+
+    /* return object type */
+    return Pin;
 }
 
 
@@ -617,6 +1289,85 @@ KsProcessPinUpdate(
     return FALSE;
 }
 
+NTSTATUS
+IKsPin_PrepareStreamHeader(
+    IN IKsPinImpl * This,
+    IN PKSISTREAM_POINTER StreamPointer)
+{
+    PKSSTREAM_HEADER Header;
+    ULONG Length;
+
+    /* grab new irp */
+    StreamPointer->Irp = KsRemoveIrpFromCancelableQueue(&This->IrpList, &This->IrpListLock, KsListEntryHead, KsAcquireAndRemoveOnlySingleItem);
+    if (!StreamPointer->Irp)
+    {
+        /* run out of mappings */
+        DPRINT("OutOfMappings\n");
+        return STATUS_DEVICE_NOT_READY;
+    }
+
+    InterlockedDecrement(&This->IrpCount);
+    KsDecrementCountedWorker(This->PinWorker);
+
+    /* get stream header */
+    if (StreamPointer->Irp->RequestorMode == UserMode)
+        Header = (PKSSTREAM_HEADER)StreamPointer->Irp->AssociatedIrp.SystemBuffer;
+    else
+        Header = (PKSSTREAM_HEADER)StreamPointer->Irp->UserBuffer;
+
+    /* initialize stream pointer */
+    StreamPointer->Callback = NULL;
+    StreamPointer->Length = max(Header->DataUsed, Header->FrameExtent);
+    StreamPointer->Next = NULL;
+    StreamPointer->Offset = 0;
+    StreamPointer->Pin = &This->Pin;
+    StreamPointer->Data = Header->Data;
+
+    StreamPointer->StreamPointer.Context = NULL;
+    StreamPointer->StreamPointer.Pin = &This->Pin;
+    StreamPointer->StreamPointer.StreamHeader = Header;
+
+    if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN)
+        StreamPointer->StreamPointer.Offset = &StreamPointer->StreamPointer.OffsetIn;
+    else
+    StreamPointer->StreamPointer.Offset = &StreamPointer->StreamPointer.OffsetOut;
+
+    StreamPointer->StreamPointer.Offset->Alignment = 0;
+    StreamPointer->StreamPointer.Offset->Count = 0;
+    StreamPointer->StreamPointer.Offset->Data = NULL;
+    StreamPointer->StreamPointer.Offset->Remaining = 0;
+
+    ASSERT(StreamPointer->StreamPointer.Offset->Remaining == 0);
+
+    //StreamPointer->Offset += StreamPointer->StreamPointer.Offset->Count;
+
+    ASSERT(StreamPointer->Length > StreamPointer->Offset);
+    ASSERT(StreamPointer->StreamPointer.StreamHeader);
+    ASSERT(This->FrameSize);
+
+    /* calculate length */
+    /* TODO split into frames */
+    Length = StreamPointer->Length;
+
+    /* FIXME */
+    ASSERT(Length);
+
+    StreamPointer->StreamPointer.Offset->Alignment = 0;
+    StreamPointer->StreamPointer.Context = NULL;
+    StreamPointer->StreamPointer.Pin = &This->Pin;
+    StreamPointer->StreamPointer.Offset->Count = Length;
+    StreamPointer->StreamPointer.Offset->Remaining = Length;
+    StreamPointer->StreamPointer.Offset->Data = (PVOID)((ULONG_PTR)StreamPointer->Data + StreamPointer->Offset);
+    StreamPointer->StreamPointer.StreamHeader->FrameExtent = Length;
+    if (StreamPointer->StreamPointer.StreamHeader->DataUsed)
+        StreamPointer->StreamPointer.StreamHeader->DataUsed = Length;
+
+    StreamPointer->StreamPointer.StreamHeader->Data = StreamPointer->StreamPointer.Offset->Data;
+
+    return STATUS_SUCCESS;
+}
+
+
 /*
     @unimplemented
 */
@@ -627,9 +1378,31 @@ KsPinGetLeadingEdgeStreamPointer(
     IN PKSPIN Pin,
     IN KSSTREAM_POINTER_STATE State)
 {
-    UNIMPLEMENTED
-    DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x\n", Pin, State);
-    return NULL;
+    IKsPinImpl * This;
+    NTSTATUS Status;
+
+    This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
+
+    DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x Count %lu Remaining %lu\n", Pin, State,
+           This->LeadingEdgeStreamPointer.Length,
+           This->LeadingEdgeStreamPointer.Offset);
+
+    /* sanity check */
+    ASSERT(State == KSSTREAM_POINTER_STATE_LOCKED);
+
+    if (State == KSSTREAM_POINTER_STATE_LOCKED)
+    {
+        if (!This->LeadingEdgeStreamPointer.Irp || This->LeadingEdgeStreamPointer.StreamPointer.Offset->Remaining == 0)
+        {
+            Status = IKsPin_PrepareStreamHeader(This, &This->LeadingEdgeStreamPointer);
+            if (!NT_SUCCESS(Status))
+                return NULL;
+        }
+
+        DPRINT("KsPinGetLeadingEdgeStreamPointer NewOffset %lu TotalLength %lu\n", This->LeadingEdgeStreamPointer.Offset, This->LeadingEdgeStreamPointer.Length);
+    }
+
+     return &This->LeadingEdgeStreamPointer.StreamPointer;
 }
 
 /*
@@ -683,8 +1456,11 @@ KsStreamPointerUnlock(
     IN PKSSTREAM_POINTER StreamPointer,
     IN BOOLEAN Eject)
 {
-    UNIMPLEMENTED
-    DPRINT("KsStreamPointerUnlock\n");
+    PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer);
+
+    DPRINT("KsStreamPointerUnlock StreamPointer %pEject %lu\n", StreamPointer, Eject);
+
+    Pointer->Irp = NULL;
 }
 
 /*
@@ -699,8 +1475,8 @@ KsStreamPointerAdvanceOffsetsAndUnlock(
     IN ULONG OutUsed,
     IN BOOLEAN Eject)
 {
-    DPRINT("KsStreamPointerAdvanceOffsets\n");
-
+    DPRINT("KsStreamPointerAdvanceOffsets InUsed %lu OutUsed %lu Eject %lu\n", InUsed, OutUsed, Eject);
+    DbgBreakPoint();
     UNIMPLEMENTED
 }
 
@@ -715,10 +1491,10 @@ KsStreamPointerDelete(
 {
     IKsPinImpl * This;
     PKSISTREAM_POINTER Cur, Last;
-    PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
-
-    DPRINT("KsStreamPointerDelete\n");
+    PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer);
 
+    DPRINT("KsStreamPointerDelete %p\n", Pointer);
+DbgBreakPoint();
     This = (IKsPinImpl*)CONTAINING_RECORD(Pointer->StreamPointer.Pin, IKsPinImpl, Pin);
 
     /* point to first stream pointer */
@@ -748,29 +1524,95 @@ KsStreamPointerDelete(
         Last->Next = Pointer->Next;
     }
 
-    /* FIXME make sure no timeouts are pending */
-    FreeItem(Pointer);
-}
+    /* FIXME make sure no timeouts are pending */
+    FreeItem(Pointer);
+}
+
+/*
+    @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsStreamPointerClone(
+    IN PKSSTREAM_POINTER StreamPointer,
+    IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL,
+    IN ULONG ContextSize,
+    OUT PKSSTREAM_POINTER* CloneStreamPointer)
+{
+    IKsPinImpl * This;
+    PKSISTREAM_POINTER CurFrame;
+    PKSISTREAM_POINTER NewFrame;
+    ULONG RefCount;
+    NTSTATUS Status;
+    ULONG Size;
+
+    DPRINT("KsStreamPointerClone StreamPointer %p CancelCallback %p ContextSize %p CloneStreamPointer %p\n", StreamPointer, CancelCallback, ContextSize, CloneStreamPointer);
+
+    /* get stream pointer */
+    CurFrame = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer);
+
+    /* calculate context size */
+    Size = sizeof(KSISTREAM_POINTER) + ContextSize;
+
+    /* allocate new stream pointer */
+    NewFrame = (PKSISTREAM_POINTER)ExAllocatePool(NonPagedPool, Size);
+
+    if (!NewFrame)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* get current irp stack location */
+    RefCount = (ULONG)CurFrame->Irp->Tail.Overlay.DriverContext[0];
+
+    /* increment reference count */
+    RefCount++;
+    CurFrame->Irp->Tail.Overlay.DriverContext[0] = (PVOID)RefCount;
+
+    /* copy stream pointer */
+    RtlMoveMemory(NewFrame, CurFrame, sizeof(KSISTREAM_POINTER));
+
+    /* locate pin */
+    This = (IKsPinImpl*)CONTAINING_RECORD(CurFrame->Pin, IKsPinImpl, Pin);
+
+    /* prepare stream header in case required */
+    if (CurFrame->StreamPointer.Offset->Remaining == 0)
+    {
+        Status = IKsPin_PrepareStreamHeader(This, NewFrame);
+        if (!NT_SUCCESS(Status))
+        {
+            FreeItem(NewFrame);
+            return STATUS_DEVICE_NOT_READY;
+        }
+    }
+
+    if (ContextSize)
+        NewFrame->StreamPointer.Context = (NewFrame + 1);
 
-/*
-    @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsStreamPointerClone(
-    IN PKSSTREAM_POINTER StreamPointer,
-    IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL,
-    IN ULONG ContextSize,
-    OUT PKSSTREAM_POINTER* CloneStreamPointer)
-{
-    UNIMPLEMENTED
-    DPRINT("KsStreamPointerClone\n");
-    return STATUS_NOT_IMPLEMENTED;
+
+    if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN)
+        NewFrame->StreamPointer.Offset = &NewFrame->StreamPointer.OffsetIn;
+    else
+        NewFrame->StreamPointer.Offset = &NewFrame->StreamPointer.OffsetOut;
+
+
+
+    NewFrame->StreamPointer.Pin = &This->Pin;
+
+    ASSERT(NewFrame->StreamPointer.Pin);
+    ASSERT(NewFrame->StreamPointer.Context);
+    ASSERT(NewFrame->StreamPointer.Offset);
+    ASSERT(NewFrame->StreamPointer.StreamHeader);
+
+    /* store result */
+    *CloneStreamPointer = &NewFrame->StreamPointer;
+
+    DPRINT("KsStreamPointerClone CloneStreamPointer %p\n", *CloneStreamPointer);
+
+    return STATUS_SUCCESS;
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 NTSTATUS
@@ -781,8 +1623,52 @@ KsStreamPointerAdvanceOffsets(
     IN ULONG OutUsed,
     IN BOOLEAN Eject)
 {
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    PKSISTREAM_POINTER CurFrame;
+    IKsPinImpl * This;
+    NTSTATUS Status;
+
+    DPRINT("KsStreamPointerAdvanceOffsets StreamPointer %p InUsed %lu OutUsed %lu Eject %lu\n", StreamPointer, InUsed, OutUsed, Eject);
+
+    /* get stream pointer */
+    CurFrame = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer);
+
+    /* locate pin */
+    This = (IKsPinImpl*)CONTAINING_RECORD(CurFrame->Pin, IKsPinImpl, Pin);
+
+    /* TODO */
+    ASSERT(InUsed == 0);
+    ASSERT(Eject == 0);
+    ASSERT(OutUsed);
+
+    DPRINT("KsStreamPointerAdvanceOffsets Offset %lu Length %lu NewOffset %lu Remaining %lu LeadingEdge %p DataUsed %lu\n", CurFrame->Offset, CurFrame->Length, CurFrame->Offset + OutUsed,
+CurFrame->StreamPointer.OffsetOut.Remaining, &This->LeadingEdgeStreamPointer.StreamPointer, CurFrame->StreamPointer.StreamHeader->DataUsed);
+DbgBreakPoint();
+
+    if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN)
+    {
+        ASSERT(CurFrame->StreamPointer.OffsetIn.Remaining >= InUsed);
+        CurFrame->StreamPointer.OffsetIn.Remaining -= InUsed;
+        CurFrame->StreamPointer.OffsetIn.Data = (PVOID)((ULONG_PTR)CurFrame->StreamPointer.OffsetIn.Data + InUsed);
+    }
+    else
+    {
+        if (!CurFrame->StreamPointer.OffsetOut.Remaining)
+        {
+            Status = IKsPin_PrepareStreamHeader(This, CurFrame);
+            if (!NT_SUCCESS(Status))
+            {
+                return STATUS_DEVICE_NOT_READY;
+            }
+        }
+        else
+        {
+            ASSERT(CurFrame->StreamPointer.OffsetOut.Remaining >= OutUsed);
+            CurFrame->StreamPointer.OffsetOut.Remaining -= OutUsed;
+            CurFrame->StreamPointer.OffsetOut.Data = (PVOID)((ULONG_PTR)CurFrame->StreamPointer.OffsetOut.Data + OutUsed);
+        }
+    }
+
+    return STATUS_SUCCESS;
 }
 
 /*
@@ -795,6 +1681,7 @@ KsStreamPointerAdvance(
     IN PKSSTREAM_POINTER StreamPointer)
 {
     UNIMPLEMENTED
+    DbgBreakPoint();
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -838,7 +1725,10 @@ KsStreamPointerScheduleTimeout(
     IN ULONGLONG Interval)
 {
     LARGE_INTEGER DueTime;
-    PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
+    PKSISTREAM_POINTER Pointer;
+
+    /* get stream pointer */
+    Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer);
 
     /* setup timer callback */
     Pointer->Callback = Callback;
@@ -860,7 +1750,10 @@ NTAPI
 KsStreamPointerCancelTimeout(
     IN PKSSTREAM_POINTER StreamPointer)
 {
-    PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
+    PKSISTREAM_POINTER Pointer;
+
+    /* get stream pointer */
+    Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer);
 
     KeCancelTimer(&Pointer->Timer);
 
@@ -880,6 +1773,10 @@ KsPinGetFirstCloneStreamPointer(
     DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin);
 
     This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
+
+    if (!This->ClonedStreamPointer)
+        return NULL;
+
     /* return first cloned stream pointer */
     return &This->ClonedStreamPointer->StreamPointer;
 }
@@ -893,9 +1790,12 @@ NTAPI
 KsStreamPointerGetNextClone(
     IN PKSSTREAM_POINTER StreamPointer)
 {
-    PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
+    PKSISTREAM_POINTER Pointer;
 
     DPRINT("KsStreamPointerGetNextClone\n");
+DbgBreakPoint();
+    /* get stream pointer */
+    Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer);
 
     /* is there a another cloned stream pointer */
     if (!Pointer->Next)
@@ -905,67 +1805,174 @@ KsStreamPointerGetNextClone(
     return &Pointer->Next->StreamPointer;
 }
 
+VOID
+NTAPI
+IKsPin_PinCentricWorker(
+    IN PVOID Parameter)
+{
+    NTSTATUS Status;
+    IKsPinImpl * This = (IKsPinImpl*)Parameter;
+
+    DPRINT("IKsPin_PinCentricWorker\n");
+
+    /* sanity checks */
+    ASSERT(This);
+    ASSERT(This->Pin.Descriptor);
+    ASSERT(This->Pin.Descriptor->Dispatch);
+    ASSERT(This->Pin.Descriptor->Dispatch->Process);
+    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
+    ASSERT(!(This->Pin.Descriptor->Flags & KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING));
+    ASSERT(!(This->Pin.Descriptor->Flags & KSPIN_FLAG_GENERATE_MAPPINGS));
+
+    do
+    {
+        DPRINT("IKsPin_PinCentricWorker calling Pin Process Routine\n");
+
+        Status = This->Pin.Descriptor->Dispatch->Process(&This->Pin);
+        DPRINT("IKsPin_PinCentricWorker Status %lx, Offset %lu Length %lu\n", Status,
+               This->LeadingEdgeStreamPointer.Offset,
+               This->LeadingEdgeStreamPointer.Length);
+        break;
+
+    }while(This->IrpCount);
+}
+
+
 NTSTATUS
-IKsPin_DispatchKsProperty(
+NTAPI
+IKsPin_DispatchKsStream(
     PDEVICE_OBJECT DeviceObject,
     PIRP Irp,
     IKsPinImpl * This)
 {
-    NTSTATUS Status;
-    PKSPROPERTY Property;
+    PKSPROCESSPIN_INDEXENTRY ProcessPinIndex;
+    PKSSTREAM_HEADER Header;
+    ULONG NumHeaders;
+    PKSFILTER Filter;
     PIO_STACK_LOCATION IoStack;
-    UNICODE_STRING GuidString;
-    ULONG PropertySetsCount = 0, PropertyItemSize = 0;
-    const KSPROPERTY_SET* PropertySets = NULL;
+    NTSTATUS Status = STATUS_SUCCESS;
 
-    /* sanity check */
-    ASSERT(This->Pin.Descriptor);
+    DPRINT("IKsPin_DispatchKsStream\n");
 
-    /* get current irp stack */
+    /* FIXME handle reset states */
+    ASSERT(This->Pin.ResetState == KSRESET_END);
+
+    /* get current stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
+    /* probe stream pointer */
+    if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM)
+        Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, This->Pin.StreamHeaderSize);
+    else
+        Status = KsProbeStreamIrp(Irp, KSSTREAM_READ  | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, This->Pin.StreamHeaderSize);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("KsProbeStreamIrp failed with %x\n", Status);
+
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
+    }
+
+    if (Irp->RequestorMode == UserMode)
+        Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
+    else
+        Header = (PKSSTREAM_HEADER)Irp->UserBuffer;
 
-    if (This->Pin.Descriptor->AutomationTable)
+    if (!Header)
     {
-        /* use available driver property sets */
-        PropertySetsCount = This->Pin.Descriptor->AutomationTable->PropertySetsCount;
-        PropertySets = This->Pin.Descriptor->AutomationTable->PropertySets;
-        PropertyItemSize = This->Pin.Descriptor->AutomationTable->PropertyItemSize;
+        DPRINT("NoHeader Canceling Irp %p\n", Irp);
+        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
     }
 
+    /* calculate num headers */
+    NumHeaders = IoStack->Parameters.DeviceIoControl.OutputBufferLength / Header->Size;
 
-    /* try driver provided property sets */
-    Status = KspPropertyHandler(Irp,
-                                PropertySetsCount,
-                                PropertySets,
-                                NULL,
-                                PropertyItemSize);
+    /* assume headers of same length */
+    ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength % Header->Size == 0);
 
-    DPRINT("IKsPin_DispatchKsProperty PropertySetCount %lu Status %lu\n", PropertySetsCount, Status);
+    /* FIXME support multiple stream headers */
+    ASSERT(NumHeaders == 1);
 
-    if (Status != STATUS_NOT_FOUND)
+    if (Irp->RequestorMode == UserMode)
     {
-        /* property was handled by driver */
-        if (Status != STATUS_PENDING)
+        /* prepare header */
+        ASSERT(Irp->MdlAddress);
+        Header->Data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
+
+        if (!Header->Data)
         {
-            Irp->IoStatus.Status = Status;
+            DPRINT("NoHeader->Data Canceling Irp %p\n", Irp);
+            Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
             IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return Status;
         }
-        return Status;
+
     }
 
-    /* property was not handled */
-    Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
 
-    RtlStringFromGUID(&Property->Set, &GuidString);
-    DPRINT("IKsPin_DispatchKsProperty Unhandled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
-    RtlFreeUnicodeString(&GuidString);
 
-    Irp->IoStatus.Status = STATUS_NOT_FOUND;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    if (This->Pin.Descriptor->Dispatch->Process)
+    {
+        /* it is a pin centric avstream */
+
+        /* mark irp as pending */
+        IoMarkIrpPending(Irp);
+
+        /* add irp to cancelable queue */
+        KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL /* FIXME */);
+
+        /* sanity checks */
+        ASSERT(!(This->Pin.Descriptor->Flags & KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING));
+        ASSERT(This->PinWorker);
+
+        InterlockedIncrement(&This->IrpCount);
+
+        DPRINT("IKsPin_DispatchKsStream IrpCount %lu\n", This->IrpCount);
+
+        /* start the processing loop */
+        KsIncrementCountedWorker(This->PinWorker);
+
+        Status = STATUS_PENDING;
+    }
+    else
+    {
+        /* filter-centric avstream */
+        ASSERT(This->Filter);
+
+        ProcessPinIndex = This->Filter->lpVtbl->GetProcessDispatch(This->Filter);
+        Filter = This->Filter->lpVtbl->GetStruct(This->Filter);
+
+        ASSERT(ProcessPinIndex);
+        ASSERT(Filter);
+        ASSERT(Filter->Descriptor);
+        ASSERT(Filter->Descriptor->Dispatch);
+
+        if (!Filter->Descriptor->Dispatch->Process)
+        {
+            /* invalid device request */
+            DPRINT("Filter Centric Processing No Process Routine\n");
+            Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_UNSUCCESSFUL;
+        }
+
+        /* mark irp as pending */
+        IoMarkIrpPending(Irp);
 
-    return STATUS_NOT_FOUND;
+        /* add irp to cancelable queue */
+        KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL /* FIXME */);
 
+        Status = Filter->Descriptor->Dispatch->Process(Filter, ProcessPinIndex);
+
+        DPRINT("IKsPin_DispatchKsStream FilterCentric: Status %lx \n", Status);
+
+    }
+
+    return Status;
 }
 
 NTSTATUS
@@ -977,7 +1984,10 @@ IKsPin_DispatchDeviceIoControl(
     PIO_STACK_LOCATION IoStack;
     PKSIOBJECT_HEADER ObjectHeader;
     IKsPinImpl * This;
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
+    UNICODE_STRING GuidString;
+    PKSPROPERTY Property;
+    ULONG SetCount = 0;
 
     /* get current irp stack */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -992,43 +2002,99 @@ IKsPin_DispatchDeviceIoControl(
     /* locate ks pin implemention from KSPIN offset */
     This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
 
-    if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
+    /* current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM ||
+        IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM)
     {
-        /* handle ks properties */
-        return IKsPin_DispatchKsProperty(DeviceObject, Irp, This);
+        /* handle ks stream packets */
+        return IKsPin_DispatchKsStream(DeviceObject, Irp, This);
     }
 
+    /* get property from input buffer */
+    Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+    /* sanity check */
+    ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER));
+    ASSERT(This->Pin.Descriptor->AutomationTable);
+
+    RtlStringFromGUID(&Property->Set, &GuidString);
+    DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
+    RtlFreeUnicodeString(&GuidString);
+
 
-    if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_WRITE_STREAM && IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_READ_STREAM)
+    if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD)
     {
-        UNIMPLEMENTED;
-        Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
-        Irp->IoStatus.Information = 0;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-        return STATUS_NOT_IMPLEMENTED;
+        const KSMETHOD_SET *MethodSet = NULL;
+        ULONG MethodItemSize = 0;
+
+        /* check if the driver supports method sets */
+        if (This->Pin.Descriptor->AutomationTable->MethodSetsCount)
+        {
+            SetCount = This->Pin.Descriptor->AutomationTable->MethodSetsCount;
+            MethodSet = This->Pin.Descriptor->AutomationTable->MethodSets;
+            MethodItemSize = This->Pin.Descriptor->AutomationTable->MethodItemSize;
+        }
+
+        /* call method set handler */
+        Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL, MethodItemSize);
     }
+    else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
+    {
+        const KSPROPERTY_SET *PropertySet = NULL;
+        ULONG PropertyItemSize = 0;
 
-    /* mark irp as pending */
-    IoMarkIrpPending(Irp);
+        /* check if the driver supports method sets */
+        if (This->Pin.Descriptor->AutomationTable->PropertySetsCount)
+        {
+            SetCount = This->Pin.Descriptor->AutomationTable->PropertySetsCount;
+            PropertySet = This->Pin.Descriptor->AutomationTable->PropertySets;
+            PropertyItemSize = This->Pin.Descriptor->AutomationTable->PropertyItemSize;
+        }
 
-    /* add irp to cancelable queue */
-    KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL /* FIXME */);
+        /* needed for our property handlers */
+        KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This;
 
-    if (This->Pin.Descriptor->Dispatch->Process)
+        /* call property handler */
+        Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize);
+    }
+    else
     {
-        /* it is a pin centric avstream */
-        Status = This->Pin.Descriptor->Dispatch->Process(&This->Pin);
+        /* sanity check */
+        ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT ||
+               IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT);
 
-        /* TODO */
+        if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
+        {
+            /* call enable event handlers */
+            Status = KspEnableEvent(Irp,
+                                    This->Pin.Descriptor->AutomationTable->EventSetsCount,
+                                    (PKSEVENT_SET)This->Pin.Descriptor->AutomationTable->EventSets,
+                                    &This->BasicHeader.EventList,
+                                    KSEVENTS_SPINLOCK,
+                                    (PVOID)&This->BasicHeader.EventListLock,
+                                    NULL,
+                                    This->Pin.Descriptor->AutomationTable->EventItemSize);
+        }
+        else
+        {
+            /* disable event handler */
+            Status = KsDisableEvent(Irp, &This->BasicHeader.EventList, KSEVENTS_SPINLOCK, &This->BasicHeader.EventListLock);
+        }
     }
-    else
+
+    RtlStringFromGUID(&Property->Set, &GuidString);
+    DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information);
+    RtlFreeUnicodeString(&GuidString);
+
+    if (Status != STATUS_PENDING)
     {
-        /* TODO
-         * filter-centric avstream 
-         */
-        UNIMPLEMENTED
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
     }
 
+    /* done */
     return Status;
 }
 
@@ -1056,9 +2122,6 @@ IKsPin_Close(
     /* locate ks pin implemention fro KSPIN offset */
     This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
 
-    /* acquire filter control mutex */
-    KsFilterAcquireControl(This->BasicHeader.Parent.KsFilter);
-
     if (This->Pin.Descriptor->Dispatch->Close)
     {
         /* call pin close routine */
@@ -1072,7 +2135,8 @@ IKsPin_Close(
             return Status;
         }
 
-        /* FIXME remove pin from filter pin list and decrement reference count */
+        /* remove pin from filter pin list and decrement reference count */
+        IKsFilter_RemovePin(This->Filter->lpVtbl->GetStruct(This->Filter), &This->Pin);
 
         if (Status != STATUS_PENDING)
         {
@@ -1104,11 +2168,80 @@ IKsPin_DispatchCreateClock(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
-    UNIMPLEMENTED;
+    PKSPIN Pin;
+    NTSTATUS Status = STATUS_SUCCESS;
+    IKsPinImpl * This;
+    KSRESOLUTION Resolution;
+    PKSRESOLUTION pResolution = NULL;
+    PKSOBJECT_CREATE_ITEM CreateItem;
 
-    Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+    DPRINT("IKsPin_DispatchCreateClock\n");
+
+    /* get the create item */
+    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
+
+    /* sanity check */
+    ASSERT(CreateItem);
+
+    /* get the pin object */
+    Pin = (PKSPIN)CreateItem->Context;
+
+    /* sanity check */
+    ASSERT(Pin);
+
+    /* locate ks pin implemention fro KSPIN offset */
+    This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
+
+    /* sanity check */
+    ASSERT(This->BasicHeader.Type == KsObjectTypePin);
+    ASSERT(This->BasicHeader.ControlMutex);
+
+    /* acquire control mutex */
+    KsAcquireControl(Pin);
+
+    if ((This->Pin.Descriptor->PinDescriptor.Communication != KSPIN_COMMUNICATION_NONE &&
+        This->Pin.Descriptor->Dispatch) ||
+        (This->Pin.Descriptor->Flags & KSPIN_FLAG_IMPLEMENT_CLOCK))
+    {
+        if (!This->DefaultClock)
+        {
+            if (This->Pin.Descriptor->Dispatch && This->Pin.Descriptor->Dispatch->Clock)
+            {
+                if (This->Pin.Descriptor->Dispatch->Clock->Resolution)
+                {
+                   This->Pin.Descriptor->Dispatch->Clock->Resolution(&This->Pin, &Resolution);
+                   pResolution = &Resolution;
+                }
+
+                Status = KsAllocateDefaultClockEx(&This->DefaultClock, 
+                                                  (PVOID)&This->Pin,
+                                                  (PFNKSSETTIMER)This->Pin.Descriptor->Dispatch->Clock->SetTimer,
+                                                  (PFNKSCANCELTIMER)This->Pin.Descriptor->Dispatch->Clock->CancelTimer,
+                                                  (PFNKSCORRELATEDTIME)This->Pin.Descriptor->Dispatch->Clock->CorrelatedTime,
+                                                  pResolution,
+                                                  0);
+            }
+            else
+            {
+                Status = KsAllocateDefaultClockEx(&This->DefaultClock, (PVOID)&This->Pin, NULL, NULL, NULL, NULL, 0);
+            }
+        }
+
+        if (NT_SUCCESS(Status))
+        {
+            Status = KsCreateDefaultClock(Irp, This->DefaultClock);
+        }
+    }
+
+    DPRINT("IKsPin_DispatchCreateClock %lx\n", Status);
+
+    /* release control mutex */
+    KsReleaseControl(Pin);
+
+    /* done */
+    Irp->IoStatus.Status = Status;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return STATUS_NOT_IMPLEMENTED;
+    return Status;
 }
 
 NTSTATUS
@@ -1141,7 +2274,7 @@ static KSDISPATCH_TABLE PinDispatchTable =
 NTSTATUS
 KspCreatePin(
     IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp, 
+    IN PIRP Irp,
     IN PKSDEVICE KsDevice,
     IN IKsFilterFactory * FilterFactory,
     IN IKsFilter* Filter,
@@ -1155,11 +2288,86 @@ KspCreatePin(
     PKSOBJECT_CREATE_ITEM CreateItem;
     NTSTATUS Status;
     PKSDATAFORMAT DataFormat;
+    PKSBASIC_HEADER BasicHeader;
+    ULONG Index;
+    ULONG FrameSize = 0;
+    ULONG NumFrames = 0;
+    KSAUTOMATION_TABLE AutomationTable;
 
     /* sanity checks */
     ASSERT(Descriptor->Dispatch);
 
-    DPRINT("KspCreatePin\n");
+    DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect->PinId, Descriptor->Flags);
+
+//Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
+//Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
+
+    DPRINT("KspCreatePin Dataflow %lu\n", Descriptor->PinDescriptor.DataFlow);
+    DPRINT("KspCreatePin Communication %lu\n", Descriptor->PinDescriptor.Communication);
+    if (Descriptor->AllocatorFraming)
+    {
+        DPRINT("KspCreatePin CountItems %lu\n", Descriptor->AllocatorFraming->CountItems);
+        DPRINT("KspCreatePin PinFlags %lx\n", Descriptor->AllocatorFraming->PinFlags);
+        DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator  %lu RatioConstantMargin %lu\n", Descriptor->AllocatorFraming->OutputCompression.RatioNumerator,
+               Descriptor->AllocatorFraming->OutputCompression.RatioDenominator, Descriptor->AllocatorFraming->OutputCompression.RatioConstantMargin);
+        DPRINT("KspCreatePin PinWeight %lx\n", Descriptor->AllocatorFraming->PinWeight);
+
+        for(Index = 0; Index < Descriptor->AllocatorFraming->CountItems; Index++)
+        {
+            DPRINT("KspCreatePin Index %lu MemoryFlags %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].MemoryFlags);
+            DPRINT("KspCreatePin Index %lu BusFlags %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].BusFlags);
+            DPRINT("KspCreatePin Index %lu Flags %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].Flags);
+            DPRINT("KspCreatePin Index %lu Frames %lu\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].Frames);
+            DPRINT("KspCreatePin Index %lu FileAlignment %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].FileAlignment);
+            DPRINT("KspCreatePin Index %lu MemoryTypeWeight %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].MemoryTypeWeight);
+            DPRINT("KspCreatePin Index %lu PhysicalRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].PhysicalRange.MinFrameSize,
+                   Descriptor->AllocatorFraming->FramingItem[Index].PhysicalRange.MaxFrameSize, 
+                   Descriptor->AllocatorFraming->FramingItem[Index].PhysicalRange.Stepping);
+
+            DPRINT("KspCreatePin Index %lu FramingRange  MinFrameSize %lu MaxFrameSize %lu Stepping %lu InPlaceWeight %lu NotInPlaceWeight %lu\n", 
+                   Index,
+                   Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.MinFrameSize,
+                   Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.MaxFrameSize,
+                   Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.Stepping,
+                   Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.InPlaceWeight,
+                   Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.NotInPlaceWeight);
+
+           FrameSize = Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.MaxFrameSize;
+           NumFrames = Descriptor->AllocatorFraming->FramingItem[Index].Frames;
+        }
+    }
+
+     for (Index = 0; Index < Descriptor->PinDescriptor.DataRangesCount; Index++)
+     {
+         UNICODE_STRING GuidString;
+         /* convert the guid to string */
+         RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->MajorFormat, &GuidString);
+         DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer);
+         RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &GuidString);
+         DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer);
+         RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString);
+         DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer);
+         RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString);
+         DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index,
+                Descriptor->PinDescriptor.DataRanges[Index]->FormatSize, Descriptor->PinDescriptor.DataRanges[Index]->Flags, Descriptor->PinDescriptor.DataRanges[Index]->SampleSize, Descriptor->PinDescriptor.DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT));
+
+         if (IsEqualGUIDAligned(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT))
+         {
+             PKS_DATARANGE_BDA_TRANSPORT Transport = (PKS_DATARANGE_BDA_TRANSPORT)&Descriptor->PinDescriptor.DataRanges[Index];
+             DPRINT("KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT AvgTimePerFrame %I64u ulcbPhyiscalFrame %lu ulcbPhyiscalFrameAlignment %lu ulcbPhyiscalPacket %lu\n", Transport->BdaTransportInfo.AvgTimePerFrame, Transport->BdaTransportInfo.ulcbPhyiscalFrame,
+                    Transport->BdaTransportInfo.ulcbPhyiscalFrameAlignment, Transport->BdaTransportInfo.ulcbPhyiscalPacket);
+         }
+    }
+    if (!FrameSize)
+    {
+        /* default to 50 * 188 (MPEG2 TS packet size) */
+        FrameSize = 9400;
+    }
+
+    if (!NumFrames)
+    {
+        NumFrames = 8;
+    }
 
     /* get current irp stack */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -1168,7 +2376,7 @@ KspCreatePin(
     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
     /* get ks device interface */
-    Device = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
+    Device = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
 
     /* first allocate pin ctx */
     This = AllocateItem(NonPagedPool, sizeof(IKsPinImpl));
@@ -1192,19 +2400,31 @@ KspCreatePin(
     This->BasicHeader.KsDevice = KsDevice;
     This->BasicHeader.Type = KsObjectTypePin;
     This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter);
-    KeInitializeMutex(&This->BasicHeader.ControlMutex, 0);
+    This->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsPin;
+    InitializeListHead(&This->BasicHeader.EventList);
+    KeInitializeSpinLock(&This->BasicHeader.EventListLock);
+
+    ASSERT(This->BasicHeader.Parent.KsFilter);
+
+    BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)This->BasicHeader.Parent.KsFilter - sizeof(KSBASIC_HEADER));
+
+    This->BasicHeader.ControlMutex = BasicHeader->ControlMutex;
+    ASSERT(This->BasicHeader.ControlMutex);
+
     InitializeListHead(&This->BasicHeader.EventList);
     KeInitializeSpinLock(&This->BasicHeader.EventListLock);
 
     /* initialize pin */
-    This->lpVtbl = &vt_IKsPin;
+    This->FrameSize = FrameSize;
+    This->NumFrames = NumFrames;
+    This->lpVtblReferenceClock = &vt_ReferenceClock;
     This->ref = 1;
     This->FileObject = IoStack->FileObject;
+    This->Filter = Filter;
     KeInitializeMutex(&This->ProcessingMutex, 0);
     InitializeListHead(&This->IrpList);
     KeInitializeSpinLock(&This->IrpListLock);
 
-
     /* allocate object bag */
     This->Pin.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG));
     if (!This->Pin.Bag)
@@ -1216,13 +2436,45 @@ KspCreatePin(
     }
 
     /* initialize object bag */
-    Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, &This->BasicHeader.ControlMutex); /* is using control mutex right? */
+    Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, NULL);
+
+    /* allocate pin descriptor */
+    This->Pin.Descriptor = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR_EX));
+    if (!This->Pin.Descriptor)
+    {
+        /* not enough memory */
+        KsFreeObjectBag(This->Pin.Bag);
+        FreeItem(This);
+        FreeItem(CreateItem);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* copy pin descriptor */
+    RtlMoveMemory((PVOID)This->Pin.Descriptor, Descriptor, sizeof(KSPIN_DESCRIPTOR_EX));
+
+    /* initialize automation table */
+    RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE));
+
+    AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM);
+    AutomationTable.PropertySets = PinPropertySet;
+    AutomationTable.PropertySetsCount = sizeof(PinPropertySet) / sizeof(KSPROPERTY_SET);
+
+    /* merge in pin property sets */
+    Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Pin.Descriptor->AutomationTable, (PKSAUTOMATION_TABLE)Descriptor->AutomationTable, &AutomationTable, This->Pin.Bag);
+
+    if (!NT_SUCCESS(Status))
+    {
+        /* not enough memory */
+        KsFreeObjectBag(This->Pin.Bag);
+        FreeItem(This);
+        FreeItem(CreateItem);
+        return Status;
+    }
 
     /* get format */
     DataFormat = (PKSDATAFORMAT)(Connect + 1);
 
-    /* initialize ks pin descriptor */
-    This->Pin.Descriptor = Descriptor;
+    /* initialize pin descriptor */
     This->Pin.Context = NULL;
     This->Pin.Id = Connect->PinId;
     This->Pin.Communication = Descriptor->PinDescriptor.Communication;
@@ -1253,19 +2505,19 @@ KspCreatePin(
     This->Pin.ClientState = KSSTATE_STOP;
 
     /* intialize allocator create item */
-    CreateItem[0].Context = (PVOID)This;
+    CreateItem[0].Context = (PVOID)&This->Pin;
     CreateItem[0].Create = IKsPin_DispatchCreateAllocator;
     CreateItem[0].Flags = KSCREATE_ITEM_FREEONSTOP;
     RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Allocator);
 
     /* intialize clock create item */
-    CreateItem[1].Context = (PVOID)This;
+    CreateItem[1].Context = (PVOID)&This->Pin;
     CreateItem[1].Create = IKsPin_DispatchCreateClock;
     CreateItem[1].Flags = KSCREATE_ITEM_FREEONSTOP;
     RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_Clock);
 
     /* intialize topology node create item */
-    CreateItem[2].Context = (PVOID)This;
+    CreateItem[2].Context = (PVOID)&This->Pin;
     CreateItem[2].Create = IKsPin_DispatchCreateNode;
     CreateItem[2].Flags = KSCREATE_ITEM_FREEONSTOP;
     RtlInitUnicodeString(&CreateItem[2].ObjectClass, KSSTRING_TopologyNode);
@@ -1286,18 +2538,24 @@ KspCreatePin(
 
      /* add extra info to object header */
     This->ObjectHeader->Type = KsObjectTypePin;
-    This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
+    This->ObjectHeader->Unknown = (PUNKNOWN)&This->BasicHeader.OuterUnknown;
     This->ObjectHeader->ObjectType = (PVOID)&This->Pin;
 
-    /* setup process pin */
-    This->ProcessPin.Pin = &This->Pin;
-    This->ProcessPin.StreamPointer = (PKSSTREAM_POINTER)This->LeadingEdgeStreamPointer;
-
     if (!Descriptor->Dispatch || !Descriptor->Dispatch->Process)
     {
         /* the pin is part of filter-centric processing filter
          * add process pin to filter
          */
+        This->ProcessPin.BytesAvailable = 0;
+        This->ProcessPin.BytesUsed = 0;
+        This->ProcessPin.CopySource = NULL;
+        This->ProcessPin.Data = NULL;
+        This->ProcessPin.DelegateBranch = NULL;
+        This->ProcessPin.Flags = 0;
+        This->ProcessPin.InPlaceCounterpart = NULL;
+        This->ProcessPin.Pin = &This->Pin;
+        This->ProcessPin.StreamPointer = (PKSSTREAM_POINTER)&This->LeadingEdgeStreamPointer.StreamPointer;
+        This->ProcessPin.Terminate = FALSE;
 
         Status = Filter->lpVtbl->AddProcessPin(Filter, &This->ProcessPin);
         DPRINT("KspCreatePin AddProcessPin %lx\n", Status);
@@ -1307,13 +2565,51 @@ KspCreatePin(
             /* failed to add process pin */
             KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
             KsFreeObjectHeader(&This->ObjectHeader);
-
+            FreeItem(This);
+            FreeItem(CreateItem);
             /* return failure code */
             return Status;
         }
     }
+    else if (Descriptor->Dispatch && Descriptor->Dispatch->Process)
+    {
+        /* pin centric processing filter */
+
+        /* initialize work item */
+        ExInitializeWorkItem(&This->PinWorkQueueItem, IKsPin_PinCentricWorker, (PVOID)This);
+
+        /* allocate counted work item */
+        Status = KsRegisterCountedWorker(HyperCriticalWorkQueue, &This->PinWorkQueueItem, &This->PinWorker);
+
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("Failed to register Worker %lx\n", Status);
+            KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
+            KsFreeObjectHeader(&This->ObjectHeader);
+            FreeItem(This);
+            FreeItem(CreateItem);
+            return Status;
+        }
+
+        if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN)
+            This->LeadingEdgeStreamPointer.StreamPointer.Offset = &This->LeadingEdgeStreamPointer.StreamPointer.OffsetIn;
+        else
+            This->LeadingEdgeStreamPointer.StreamPointer.Offset = &This->LeadingEdgeStreamPointer.StreamPointer.OffsetOut;
+
+
+        KeInitializeEvent(&This->FrameComplete, NotificationEvent, FALSE);
+
+    }
 
     /* FIXME add pin instance to filter instance */
+    IKsFilter_AddPin(Filter->lpVtbl->GetStruct(Filter), &This->Pin);
+
+    if (Descriptor->Dispatch && Descriptor->Dispatch->SetDataFormat)
+    {
+        Status = Descriptor->Dispatch->SetDataFormat(&This->Pin, NULL, NULL, This->Pin.ConnectionFormat, NULL);
+        DPRINT("KspCreatePin SetDataFormat %lx\n", Status);
+    }
+
 
     /* does the driver have a pin dispatch */
     if (Descriptor->Dispatch && Descriptor->Dispatch->Create)
@@ -1323,11 +2619,13 @@ KspCreatePin(
         DPRINT("KspCreatePin DispatchCreate %lx\n", Status);
     }
 
-    DPRINT("KspCreatePin Status %lx\n", Status);
+
+    DPRINT("KspCreatePin Status %lx KsDevice %p\n", Status, KsDevice);
 
     if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
     {
         /* failed to create pin, release resources */
+        IKsFilter_RemovePin(Filter->lpVtbl->GetStruct(Filter), &This->Pin);
         KsFreeObjectHeader((KSOBJECT_HEADER)This->ObjectHeader);
         KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
         FreeItem(This);
index cc0b8f9..75b5141 100644 (file)
@@ -5,6 +5,7 @@
 #include <ntifs.h>
 #include <ntddk.h>
 #define NDEBUG
+//#define YDEBUG
 #include <debug.h>
 #include <portcls.h>
 #include <ks.h>
 #include "kstypes.h"
 #include "ksiface.h"
 
+#include "ksmedia.h"
+#include "bdamedia.h"
 
 #define TAG_DEVICE_HEADER 'KSDH'
+#define REG_PINFLAG_B_MANY 0x4 /* strmif.h */
+#define MERIT_DO_NOT_USE 0x200000 /* dshow.h */
 
 #define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\
     PropGeneral, PropInstances, PropIntersection)\
@@ -35,3 +40,24 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\
     DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(PropGeneral),\
     DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(PropGeneral)\
 }
+
+#define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\
+    PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\
+DEFINE_KSPROPERTY_TABLE(PinSet) {\
+    DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(PropStateHandler, PropStateHandler),\
+    DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler),\
+    DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING_EX(PropAllocatorFraming)\
+}
+
+
+#define DEFINE_KSPROPERTY_STREAMSET(PinSet,\
+    PropStreamAllocator, PropMasterClock, PropPipeId)\
+DEFINE_KSPROPERTY_TABLE(PinSet) {\
+    DEFINE_KSPROPERTY_ITEM_STREAM_ALLOCATOR(PropStreamAllocator, PropStreamAllocator),\
+    DEFINE_KSPROPERTY_ITEM_STREAM_MASTERCLOCK(PropMasterClock, PropMasterClock),\
+    DEFINE_KSPROPERTY_ITEM_STREAM_PIPE_ID(PropPipeId, PropPipeId)\
+}
+
+
+
+
index a2e759c..b1a17e3 100644 (file)
@@ -137,7 +137,7 @@ KspPropertyHandler(
     /* get input property request */
     Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
 
-    DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM));
+//    DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM));
 
     /* sanity check */
     ASSERT(PropertyItemSize == 0 || PropertyItemSize == sizeof(KSPROPERTY_ITEM));
index 87eb1e9..cc4a888 100644 (file)
@@ -270,13 +270,3 @@ KsTopologyPropertyHandler(
     return Status;
 }
 
-NTSTATUS
-NTAPI
-KspTopologyPropertyHandler(
-    IN PIRP Irp,
-    IN PKSIDENTIFIER  Request,
-    IN OUT PVOID  Data)
-{
-
-    return STATUS_NOT_IMPLEMENTED;
-}
index db58172..45a603d 100644 (file)
@@ -3,6 +3,9 @@
 #include <ntddk.h>
 #include <windef.h>
 #include <ks.h>
+#define NOBITMAP
+#include <mmreg.h>
+#include <ksmedia.h>
 #include <bdatypes.h>
 #include <bdamedia.h>
 #include <bdasup.h>
index 7605f8d..dcc4f24 100644 (file)
 PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
     BOOLEAN LockFailed = FALSE;
 
+    ASSERT(IrpSp->Parameters.DeviceIoControl.Type3InputBuffer);
+    ASSERT(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
+    ASSERT(!Irp->MdlAddress);
+
     Irp->MdlAddress =
        IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
                       IrpSp->Parameters.DeviceIoControl.InputBufferLength,
diff --git a/drivers/network/ndis/ndis.def b/drivers/network/ndis/ndis.def
deleted file mode 100644 (file)
index 5eba1a2..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-; NDIS Kernel Module - ReactOS Operating System
-
-LIBRARY NDIS.SYS
-
-EXPORTS
-ArcFilterDprIndicateReceive@16
-ArcFilterDprIndicateReceiveComplete@4
-EthFilterDprIndicateReceive@32
-EthFilterDprIndicateReceiveComplete@4
-FddiFilterDprIndicateReceive@36
-FddiFilterDprIndicateReceiveComplete@4
-NDIS_BUFFER_TO_SPAN_PAGES@4
-NdisAcquireReadWriteLock@12
-NdisAcquireSpinLock@4
-NdisAdjustBufferLength@8
-NdisAllocateBuffer@20
-NdisAllocateBufferPool@12
-NdisAllocateDmaChannel@20
-NdisAllocateFromBlockPool@4
-NdisAllocateMemory@20
-NdisAllocateMemoryWithTag@12
-NdisAllocatePacket@12
-NdisAllocatePacketPool@16
-NdisAllocatePacketPoolEx@20
-NdisAllocateSharedMemory@20
-NdisAllocateSpinLock@4
-NdisAnsiStringToUnicodeString@8
-NdisBufferLength@4
-NdisBufferVirtualAddress@4
-NdisCancelSendPackets@8
-NdisCancelTimer@8
-NdisClAddParty@16
-NdisClCloseAddressFamily@4
-NdisClCloseCall@16
-NdisClDeregisterSap@4
-NdisClDropParty@12
-NdisClGetProtocolVcContextFromTapiCallId@12
-NdisClIncomingCallComplete@12
-NdisClMakeCall@16
-NdisClModifyCallQoS@8
-NdisClOpenAddressFamily@24
-NdisClRegisterSap@16
-NdisCloseAdapter@8
-NdisCloseConfiguration@4
-NdisCloseFile@4
-NdisCmActivateVc@8
-NdisCmAddPartyComplete@16
-NdisCmCloseAddressFamilyComplete@8
-NdisCmCloseCallComplete@12
-NdisCmDeactivateVc@4
-NdisCmDeregisterSapComplete@8
-NdisCmDispatchCallConnected@4
-NdisCmDispatchIncomingCall@12
-NdisCmDispatchIncomingCallQoSChange@8
-NdisCmDispatchIncomingCloseCall@16
-NdisCmDispatchIncomingDropParty@16
-NdisCmDropPartyComplete@8
-NdisCmMakeCallComplete@20
-NdisCmModifyCallQoSComplete@12
-NdisCmOpenAddressFamilyComplete@12
-NdisCmRegisterAddressFamily@16
-NdisCmRegisterSapComplete@12
-NdisCoAssignInstanceName@12
-NdisCoCreateVc@16
-NdisCoDeleteVc@4
-NdisCoGetTapiCallId@8
-NdisCoRequest@20
-NdisCoRequestComplete@20
-NdisCoSendPackets@12
-NdisCompareAnsiString@12
-NdisCompareUnicodeString@12
-NdisCompleteBindAdapter@12
-NdisCompleteCloseAdapter@8
-NdisCompleteDmaTransfer@24
-NdisCompleteOpenAdapter@12
-NdisCompletePnPEvent@12
-NdisCompleteQueryStatistics@12
-NdisCompleteUnbindAdapter@8
-NdisConvertStringToAtmAddress@12
-NdisCopyBuffer@24
-NdisCopyFromPacketToPacket@24
-NdisCopyFromPacketToPacketSafe@28
-NdisCreateBlockPool@16
-NdisDeregisterAdapter@4
-NdisDeregisterAdapterShutdownHandler@4
-NdisDeregisterMac@8
-NdisDeregisterProtocol@8
-NdisDeregisterTdiCallBack@0
-NdisDestroyBlockPool@4
-NdisDprAcquireSpinLock@4
-NdisDprAllocatePacket@12
-NdisDprAllocatePacketNonInterlocked@12
-NdisDprFreePacket@4
-NdisDprFreePacketNonInterlocked@4
-NdisDprReleaseSpinLock@4
-NdisEqualString@12
-NdisFreeBuffer@4
-NdisFreeBufferPool@4
-NdisFreeDmaChannel@4
-NdisFreeToBlockPool@4
-NdisFreeMemory@12
-NdisFreePacket@4
-NdisFreePacketPool@4
-NdisFreeSharedMemory@24
-NdisFreeSpinLock@4
-NdisGeneratePartialCancelId@0
-NdisGetBufferPhysicalArraySize@8
-NdisGetCurrentProcessorCounts@12
-NdisGetCurrentProcessorCpuUsage@4
-NdisGetCurrentSystemTime@4
-NdisGetDriverHandle@8
-NdisGetFirstBufferFromPacket@20
-NdisGetFirstBufferFromPacketSafe@24
-NdisGetPacketCancelId@4
-NdisGetPoolFromPacket@4
-NdisGetReceivedPacket@8
-NdisGetRoutineAddress@4
-NdisGetSharedDataAlignment@0
-NdisGetSystemUpTime@4
-NdisGetVersion@0
-NdisIMAssociateMiniport@8
-NdisIMCancelInitializeDeviceInstance@8
-NdisIMCopySendCompletePerPacketInfo@8
-NdisIMCopySendPerPacketInfo@8
-NdisIMDeInitializeDeviceInstance@4
-NdisIMDeregisterLayeredMiniport@4
-NdisIMGetBindingContext@4
-NdisIMGetCurrentPacketStack@8
-NdisIMGetDeviceContext@4
-NdisIMInitializeDeviceInstance@8
-NdisIMInitializeDeviceInstanceEx@12
-NdisIMNotifyPnPEvent@8
-NdisImmediateReadPciSlotInformation@20
-NdisImmediateReadPortUchar@12
-NdisImmediateReadPortUlong@12
-NdisImmediateReadPortUshort@12
-NdisImmediateReadSharedMemory@16
-NdisImmediateWritePciSlotInformation@20
-NdisImmediateWritePortUchar@12
-NdisImmediateWritePortUlong@12
-NdisImmediateWritePortUshort@12
-NdisImmediateWriteSharedMemory@16
-NdisIMQueueMiniportCallback@12
-NdisIMRegisterLayeredMiniport@16
-NdisIMRevertBack@8
-NdisIMSwitchToMiniport@8
-NdisInitAnsiString@8
-NdisInitializeEvent@4
-NdisInitializeReadWriteLock@4
-NdisInitializeString@8
-NdisInitializeTimer@12
-NdisInitializeWrapper@16
-NdisInitUnicodeString@8
-NdisInterlockedAddLargeInteger@16
-NdisInterlockedAddUlong@12
-NdisInterlockedDecrement@4
-NdisInterlockedIncrement@4
-NdisInterlockedInsertHeadList@12
-NdisInterlockedInsertTailList@12
-NdisInterlockedPopEntrySList@8
-NdisInterlockedPushEntrySList@12
-NdisInterlockedRemoveHeadList@8
-NdisMAllocateMapRegisters@20
-NdisMAllocateSharedMemory@20
-NdisMAllocateSharedMemoryAsync@16
-NdisMapFile@12
-NdisMapIoSpace@24
-;NdisMatchPdoWithPacket ?
-NdisMCancelTimer@8
-NdisMCloseLog@4
-NdisMCmActivateVc@8
-NdisMCmCreateVc@16
-NdisMCmDeactivateVc@4
-NdisMCmDeleteVc@4
-NdisMCmRegisterAddressFamily@16
-NdisMCmRequest@16
-NdisMCoActivateVcComplete@12
-NdisMCoDeactivateVcComplete@8
-NdisMCoIndicateReceivePacket@12
-NdisMCoIndicateStatus@20
-NdisMCompleteBufferPhysicalMapping@12
-NdisMCoReceiveComplete@4
-NdisMCoRequestComplete@12
-NdisMCoSendComplete@12
-NdisMCreateLog@12
-NdisMDeregisterAdapterShutdownHandler@4
-NdisMDeregisterDevice@4
-NdisMDeregisterDmaChannel@4
-NdisMDeregisterInterrupt@4
-NdisMDeregisterIoPortRange@16
-NdisMFlushLog@4
-NdisMFreeMapRegisters@4
-NdisMFreeSharedMemory@24
-NdisMGetDeviceProperty@24
-NdisMGetDmaAlignment@4
-NdisMIndicateStatus@16
-NdisMIndicateStatusComplete@4
-NdisMInitializeScatterGatherDma@12
-NdisMInitializeTimer@16
-NdisMMapIoSpace@20
-NdisMPciAssignResources@12
-NdisMPromoteMiniport@4
-NdisMQueryAdapterInstanceName@8
-NdisMQueryAdapterResources@16
-NdisMQueryInformationComplete@8
-NdisMReadDmaCounter@4
-NdisMRegisterAdapterShutdownHandler@12
-NdisMRegisterDevice@24
-NdisMRegisterDmaChannel@24
-NdisMRegisterInterrupt@28
-NdisMRegisterIoPortRange@16
-NdisMRegisterMiniport@12
-NdisMRegisterUnloadHandler@8
-NdisMRemoveMiniport@4
-NdisMResetComplete@12
-NdisMSendComplete@12
-NdisMSendResourcesAvailable@4
-NdisMSetAttributes@16
-NdisMSetAttributesEx@20
-NdisMSetInformationComplete@8
-NdisMSetMiniportSecondary@8
-NdisMSetPeriodicTimer@8
-NdisMSetTimer@8
-NdisMSleep@4
-NdisMStartBufferPhysicalMapping@24
-NdisMSynchronizeWithInterrupt@12
-NdisMTransferDataComplete@16
-NdisMUnmapIoSpace@12
-NdisMWanIndicateReceive@20
-NdisMWanIndicateReceiveComplete@4
-NdisMWanSendComplete@12
-NdisMWriteLogData@12
-NdisOpenAdapter@44
-NdisOpenConfiguration@12
-NdisOpenConfigurationKeyByIndex@20
-NdisOpenConfigurationKeyByName@16
-NdisOpenFile@24
-NdisOpenProtocolConfiguration@12
-NdisOverrideBusNumber@12
-NdisPacketPoolUsage@4
-NdisPacketSize@4
-NdisPciAssignResources@20
-NdisQueryAdapterInstanceName@8
-NdisQueryBindInstanceName@8
-NdisQueryBuffer@12
-NdisQueryBufferOffset@12
-NdisQueryBufferSafe@16
-NdisQueryMapRegisterCount@8
-NdisQueryPendingIOCount@8
-NdisReadConfiguration@20
-NdisReadEisaSlotInformation@16
-NdisReadEisaSlotInformationEx@20
-NdisReadMcaPosInformation@16
-NdisReadNetworkAddress@16
-NdisReadPciSlotInformation@20
-NdisReadPcmciaAttributeMemory@16
-NdisReEnumerateProtocolBindings@4
-NdisRegisterAdapter@24
-NdisRegisterAdapterShutdownHandler@12
-NdisRegisterProtocol@16
-NdisRegisterTdiCallBack@8
-NdisReleaseAdapterResources@4
-NdisReleaseReadWriteLock@8
-NdisReleaseSpinLock@4
-NdisRequest@12
-NdisReset@8
-NdisResetEvent@4
-NdisReturnPackets@8
-NdisSend@12
-NdisSendPackets@12
-NdisSetEvent@4
-NdisSetPacketCancelId@8
-NdisSetPacketPoolProtocolId@8
-NdisSetPacketStatus@16
-NdisSetProtocolFilter@32
-NdisSetTimer@8
-NdisSetTimerEx@12
-NdisSetupDmaTransfer@24
-NdisSystemProcessorCount@0
-NdisTerminateWrapper@8
-NdisTransferData@28
-NdisUnchainBufferAtBack@8
-NdisUnchainBufferAtFront@8
-NdisUnicodeStringToAnsiString@8
-NdisUnmapFile@4
-NdisUpcaseUnicodeString@8
-NdisUpdateSharedMemory@20
-NdisWaitEvent@8
-NdisWriteConfiguration@16
-NdisWriteErrorLogEntry
-NdisWriteEventLogEntry@28
-NdisWritePciSlotInformation@20
-NdisWritePcmciaAttributeMemory@16
-TrFilterDprIndicateReceive@28
-TrFilterDprIndicateReceiveComplete@4
-NdisScheduleWorkItem@4
-
-; EOF
index 39eab40..38dadef 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="ndis" type="kernelmodedriver" installbase="system32/drivers" installname="ndis.sys">
-       <importlibrary definition="ndis.def"></importlibrary>
+       <importlibrary definition="ndis.spec"></importlibrary>
        <include base="ndis">include</include>
        <define name="NDIS_WRAPPER" />
        <define name="NDIS51" />
diff --git a/drivers/network/ndis/ndis.spec b/drivers/network/ndis/ndis.spec
new file mode 100644 (file)
index 0000000..bd3eaea
--- /dev/null
@@ -0,0 +1,292 @@
+
+ @ stdcall ArcFilterDprIndicateReceive(ptr ptr ptr long)
+ @ stdcall ArcFilterDprIndicateReceiveComplete(ptr)
+ @ stdcall EthFilterDprIndicateReceive(ptr ptr ptr ptr long ptr long long)
+ @ stdcall EthFilterDprIndicateReceiveComplete(ptr)
+ @ stdcall FddiFilterDprIndicateReceive(ptr ptr ptr long ptr long ptr long long)
+ @ stdcall FddiFilterDprIndicateReceiveComplete(ptr)
+ @ stdcall NDIS_BUFFER_TO_SPAN_PAGES(ptr)
+ @ stdcall NdisAcquireReadWriteLock(ptr long ptr)
+ @ stdcall NdisAcquireSpinLock(ptr)
+ @ stdcall NdisAdjustBufferLength(ptr long)
+ @ stdcall NdisAllocateBuffer(ptr ptr ptr ptr long)
+ @ stdcall NdisAllocateBufferPool(ptr ptr long)
+ @ stdcall NdisAllocateDmaChannel(ptr ptr ptr ptr long)
+ @ stdcall NdisAllocateMemory(ptr long long double)
+ @ stdcall NdisAllocateFromBlockPool(ptr)
+ @ stdcall NdisAllocateMemoryWithTag(ptr long long)
+ @ stdcall NdisAllocatePacket(ptr ptr ptr)
+ @ stdcall NdisAllocatePacketPool(ptr ptr long long)
+ @ stdcall NdisAllocatePacketPoolEx(ptr ptr long long long)
+ @ stdcall NdisAllocateSharedMemory(ptr long long ptr ptr)
+ @ stdcall NdisAllocateSpinLock(ptr)
+ @ stdcall NdisAnsiStringToUnicodeString(ptr ptr)
+ @ stdcall NdisBufferLength(ptr)
+ @ stdcall NdisBufferVirtualAddress(ptr)
+ @ stdcall NdisCancelSendPackets(ptr ptr)
+ @ stdcall NdisCancelTimer(ptr ptr)
+ @ stdcall NdisClAddParty(ptr ptr ptr ptr)
+ @ stdcall NdisClCloseAddressFamily(ptr)
+ @ stdcall NdisClCloseCall(ptr ptr ptr long)
+ @ stdcall NdisClDeregisterSap(ptr)
+ @ stdcall NdisClDropParty(ptr ptr long)
+ @ stdcall NdisClGetProtocolVcContextFromTapiCallId(double ptr)
+ @ stdcall NdisClIncomingCallComplete(long ptr ptr)
+ @ stdcall NdisClMakeCall(ptr ptr ptr ptr)
+ @ stdcall NdisClModifyCallQoS(ptr ptr)
+ @ stdcall NdisClOpenAddressFamily(ptr ptr ptr ptr long ptr)
+ @ stdcall NdisClRegisterSap(ptr ptr ptr ptr)
+ @ stdcall NdisCloseAdapter(ptr ptr)
+ @ stdcall NdisCloseConfiguration(ptr)
+ @ stdcall NdisCloseFile(ptr)
+ @ stdcall NdisCmActivateVc(ptr ptr)
+ @ stdcall NdisCmAddPartyComplete(long ptr ptr ptr)
+ @ stdcall NdisCmCloseAddressFamilyComplete(long ptr)
+ @ stdcall NdisCmCloseCallComplete(long ptr ptr)
+ @ stdcall NdisCmDeactivateVc(ptr)
+ @ stdcall NdisCmDeregisterSapComplete(long ptr)
+ @ stdcall NdisCmDispatchCallConnected(ptr)
+ @ stdcall NdisCmDispatchIncomingCall(ptr ptr ptr)
+ @ stdcall NdisCmDispatchIncomingCallQoSChange(ptr ptr)
+ @ stdcall NdisCmDispatchIncomingCloseCall(long ptr ptr long)
+ @ stdcall NdisCmDispatchIncomingDropParty(ptr ptr ptr long)
+ @ stdcall NdisCmDropPartyComplete(long ptr)
+ @ stdcall NdisCmMakeCallComplete(long ptr ptr ptr ptr)
+ @ stdcall NdisCmModifyCallQoSComplete(long ptr ptr)
+ @ stdcall NdisCmOpenAddressFamilyComplete(long ptr ptr)
+ @ stdcall NdisCmRegisterAddressFamily(ptr ptr ptr long)
+ @ stdcall NdisCmRegisterSapComplete(long ptr ptr)
+ @ stdcall NdisCoAssignInstanceName(ptr ptr ptr)
+ @ stdcall NdisCoCreateVc(ptr ptr ptr ptr)
+ @ stdcall NdisCoDeleteVc(ptr)
+ @ stdcall NdisCoGetTapiCallId(ptr ptr)
+ @ stdcall NdisCoRequest(ptr ptr ptr ptr ptr)
+ @ stdcall NdisCoRequestComplete(long ptr ptr ptr ptr)
+ @ stdcall NdisCoSendPackets(ptr ptr long)
+ @ stdcall NdisCompareAnsiString(ptr ptr long)
+ @ stdcall NdisCompareUnicodeString(ptr ptr long)
+ @ stdcall NdisCompleteBindAdapter(ptr long long)
+ @ stdcall NdisCompleteCloseAdapter(ptr long)
+ @ stdcall NdisCompleteDmaTransfer(ptr ptr ptr long long long)
+ @ stdcall NdisCompleteOpenAdapter(ptr long long)
+ @ stdcall NdisCompletePnPEvent(long ptr ptr)
+ @ stdcall NdisCompleteQueryStatistics(ptr ptr long)
+ @ stdcall NdisCompleteUnbindAdapter(ptr long)
+ @ stdcall NdisConvertStringToAtmAddress(ptr ptr ptr)
+ @ stdcall NdisCopyBuffer(ptr ptr ptr ptr long long)
+ @ stdcall NdisCopyFromPacketToPacket(ptr long long ptr long ptr)
+ @ stdcall NdisCopyFromPacketToPacketSafe(ptr long long ptr long ptr long)
+ @ stdcall NdisCreateBlockPool(long long long ptr)
+ @ stdcall NdisDeregisterAdapter(ptr)
+ @ stdcall NdisDeregisterAdapterShutdownHandler(ptr)
+ @ stdcall NdisDeregisterMac(ptr ptr)
+ @ stdcall NdisDeregisterProtocol(ptr ptr)
+ @ stdcall NdisDeregisterTdiCallBack()
+ @ stdcall NdisDestroyBlockPool(ptr)
+ @ stdcall NdisDprAcquireSpinLock(ptr)
+ @ stdcall NdisDprAllocatePacket(ptr ptr ptr)
+ @ stdcall NdisDprAllocatePacketNonInterlocked(ptr ptr ptr)
+ @ stdcall NdisDprFreePacket(ptr)
+ @ stdcall NdisDprFreePacketNonInterlocked(ptr)
+ @ stdcall NdisDprReleaseSpinLock(ptr)
+ @ stdcall NdisEqualString(ptr ptr long)
+ @ stdcall NdisFreeBuffer(ptr)
+ @ stdcall NdisFreeBufferPool(ptr)
+ @ stdcall NdisFreeDmaChannel(ptr)
+ @ stdcall NdisFreeToBlockPool(ptr)
+ @ stdcall NdisFreeMemory(ptr long long)
+ @ stdcall NdisFreePacket(ptr)
+ @ stdcall NdisFreePacketPool(ptr)
+ @ stdcall NdisFreeSharedMemory(ptr long long ptr double)
+ @ stdcall NdisFreeSpinLock(ptr)
+ @ stdcall NdisGeneratePartialCancelId()
+ @ stdcall NdisGetBufferPhysicalArraySize(ptr ptr)
+ @ stdcall NdisGetCurrentProcessorCounts(ptr ptr ptr)
+ @ stdcall NdisGetCurrentProcessorCpuUsage(ptr)
+ @ stdcall NdisGetCurrentSystemTime(ptr)
+ @ stdcall NdisGetDriverHandle(ptr ptr)
+ @ stdcall NdisGetFirstBufferFromPacket(ptr ptr ptr ptr ptr)
+ @ stdcall NdisGetFirstBufferFromPacketSafe(ptr ptr ptr ptr ptr long)
+ @ stdcall NdisGetPacketCancelId(ptr)
+ @ stdcall NdisGetPoolFromPacket(ptr)
+ @ stdcall NdisGetReceivedPacket(ptr ptr)
+ @ stdcall NdisGetRoutineAddress(ptr)
+ @ stdcall NdisGetSharedDataAlignment()
+ @ stdcall NdisGetSystemUpTime(ptr)
+ @ stdcall NdisGetVersion()
+ @ stdcall NdisIMAssociateMiniport(ptr ptr)
+ @ stdcall NdisIMCancelInitializeDeviceInstance(ptr ptr)
+ @ stdcall NdisIMCopySendCompletePerPacketInfo(ptr ptr)
+ @ stdcall NdisIMCopySendPerPacketInfo(ptr ptr)
+ @ stdcall NdisIMDeInitializeDeviceInstance(ptr)
+ @ stdcall NdisIMDeregisterLayeredMiniport(ptr)
+ @ stdcall NdisIMGetBindingContext(ptr)
+ @ stdcall NdisIMGetCurrentPacketStack(ptr ptr)
+ @ stdcall NdisIMGetDeviceContext(ptr)
+ @ stdcall NdisIMInitializeDeviceInstance(ptr ptr)
+ @ stdcall NdisIMInitializeDeviceInstanceEx(ptr ptr ptr)
+ @ stdcall NdisIMNotifyPnPEvent(ptr ptr)
+ @ stdcall NdisImmediateReadPciSlotInformation(ptr long long ptr long)
+ @ stdcall NdisImmediateReadPortUchar(ptr long ptr)
+ @ stdcall NdisImmediateReadPortUlong(ptr long ptr)
+ @ stdcall NdisImmediateReadPortUshort(ptr long ptr)
+ @ stdcall NdisImmediateReadSharedMemory(ptr long ptr long)
+ @ stdcall NdisImmediateWritePciSlotInformation(ptr long long ptr long)
+ @ stdcall NdisImmediateWritePortUchar(ptr long long)
+ @ stdcall NdisImmediateWritePortUlong(ptr long long)
+ @ stdcall NdisImmediateWritePortUshort(ptr long long)
+ @ stdcall NdisImmediateWriteSharedMemory(ptr long ptr long)
+ @ stdcall NdisIMQueueMiniportCallback(ptr ptr ptr)
+ @ stdcall NdisIMRegisterLayeredMiniport(ptr ptr long ptr)
+ @ stdcall NdisIMRevertBack(ptr ptr)
+ @ stdcall NdisIMSwitchToMiniport(ptr ptr)
+ @ stdcall NdisInitAnsiString(ptr ptr)
+ @ stdcall NdisInitializeEvent(ptr)
+ @ stdcall NdisInitializeReadWriteLock(ptr)
+ @ stdcall NdisInitializeString(ptr ptr)
+ @ stdcall NdisInitializeTimer(ptr ptr ptr)
+ @ stdcall NdisInitializeWrapper(ptr ptr ptr ptr)
+ @ stdcall NdisInitUnicodeString(ptr ptr)
+ @ stdcall NdisInterlockedAddLargeInteger(ptr double ptr)
+ @ stdcall NdisInterlockedAddUlong(ptr long ptr)
+ @ stdcall NdisInterlockedDecrement(ptr)
+ @ stdcall NdisInterlockedIncrement(ptr)
+ @ stdcall NdisInterlockedInsertHeadList(ptr ptr ptr)
+ @ stdcall NdisInterlockedInsertTailList(ptr ptr ptr)
+ @ stdcall NdisInterlockedPopEntrySList(ptr ptr)
+ @ stdcall NdisInterlockedPushEntrySList(ptr ptr ptr)
+ @ stdcall NdisInterlockedRemoveHeadList(ptr ptr)
+ @ stdcall NdisMAllocateMapRegisters(ptr long long long long)
+ @ stdcall NdisMAllocateSharedMemory(ptr long long ptr ptr)
+ @ stdcall NdisMAllocateSharedMemoryAsync(ptr long long ptr)
+ @ stdcall NdisMapFile(ptr ptr ptr)
+ @ stdcall NdisMapIoSpace(ptr ptr ptr double long)
+# @ stdcall NdisMatchPdoWithPacket ?
+ @ stdcall NdisMCancelTimer(ptr ptr)
+ @ stdcall NdisMCloseLog(ptr)
+ @ stdcall NdisMCmActivateVc(ptr ptr)
+ @ stdcall NdisMCmCreateVc(ptr ptr ptr ptr)
+ @ stdcall NdisMCmDeactivateVc(ptr)
+ @ stdcall NdisMCmDeleteVc(ptr)
+ @ stdcall NdisMCmRegisterAddressFamily(ptr ptr ptr long)
+ @ stdcall NdisMCmRequest(ptr ptr ptr ptr)
+ @ stdcall NdisMCoActivateVcComplete(long ptr ptr)
+ @ stdcall NdisMCoDeactivateVcComplete(long ptr)
+ @ stdcall NdisMCoIndicateReceivePacket(ptr ptr long)
+ @ stdcall NdisMCoIndicateStatus(ptr ptr long ptr long)
+ @ stdcall NdisMCompleteBufferPhysicalMapping(ptr ptr long)
+ @ stdcall NdisMCoReceiveComplete(ptr)
+ @ stdcall NdisMCoRequestComplete(long ptr ptr)
+ @ stdcall NdisMCoSendComplete(ptr ptr ptr)
+ @ stdcall NdisMCreateLog(ptr long ptr)
+ @ stdcall NdisMDeregisterAdapterShutdownHandler(ptr)
+ @ stdcall NdisMDeregisterDevice(ptr)
+ @ stdcall NdisMDeregisterDmaChannel(ptr)
+ @ stdcall NdisMDeregisterInterrupt(ptr)
+ @ stdcall NdisMDeregisterIoPortRange(ptr long long ptr)
+ @ stdcall NdisMFlushLog(ptr)
+ @ stdcall NdisMFreeMapRegisters(ptr)
+ @ stdcall NdisMFreeSharedMemory(ptr long long ptr double)
+ @ stdcall NdisMGetDeviceProperty(ptr ptr ptr ptr ptr ptr)
+ @ stdcall NdisMGetDmaAlignment(ptr)
+ @ stdcall NdisMIndicateStatus(ptr long ptr long)
+ @ stdcall NdisMIndicateStatusComplete(ptr)
+ @ stdcall NdisMInitializeScatterGatherDma(ptr long long)
+ @ stdcall NdisMInitializeTimer(ptr ptr ptr ptr)
+ @ stdcall NdisMMapIoSpace(ptr ptr double long)
+ @ stdcall NdisMPciAssignResources(ptr long ptr)
+ @ stdcall NdisMPromoteMiniport(ptr)
+ @ stdcall NdisMQueryAdapterInstanceName(ptr ptr)
+ @ stdcall NdisMQueryAdapterResources(ptr ptr ptr ptr)
+ @ stdcall NdisMQueryInformationComplete(ptr long)
+ @ stdcall NdisMReadDmaCounter(ptr)
+ @ stdcall NdisMRegisterAdapterShutdownHandler(ptr ptr ptr)
+ @ stdcall NdisMRegisterDevice(ptr ptr ptr ptr ptr ptr)
+ @ stdcall NdisMRegisterDmaChannel(ptr ptr long long ptr long)
+ @ stdcall NdisMRegisterInterrupt(ptr ptr long long long long long)
+ @ stdcall NdisMRegisterIoPortRange(ptr ptr long long)
+ @ stdcall NdisMRegisterMiniport(ptr ptr long)
+ @ stdcall NdisMRegisterUnloadHandler(ptr ptr)
+ @ stdcall NdisMRemoveMiniport(ptr)
+ @ stdcall NdisMResetComplete(ptr long long)
+ @ stdcall NdisMSendComplete(ptr ptr long)
+ @ stdcall NdisMSendResourcesAvailable(ptr)
+ @ stdcall NdisMSetAttributes(ptr ptr long long)
+ @ stdcall NdisMSetAttributesEx(ptr ptr long long long)
+ @ stdcall NdisMSetInformationComplete(ptr long)
+ @ stdcall NdisMSetMiniportSecondary(ptr ptr)
+ @ stdcall NdisMSetPeriodicTimer(ptr long)
+ @ stdcall NdisMSetTimer(ptr long)
+ @ stdcall NdisMSleep(long)
+ @ stdcall NdisMStartBufferPhysicalMapping(ptr ptr long long ptr ptr)
+ @ stdcall NdisMSynchronizeWithInterrupt(ptr ptr ptr)
+ @ stdcall NdisMTransferDataComplete(ptr ptr long long)
+ @ stdcall NdisMUnmapIoSpace(ptr ptr long)
+ @ stdcall NdisMWanIndicateReceive(ptr ptr ptr ptr long)
+ @ stdcall NdisMWanIndicateReceiveComplete(ptr)
+ @ stdcall NdisMWanSendComplete(ptr ptr long)
+ @ stdcall NdisMWriteLogData(ptr ptr long)
+ @ stdcall NdisOpenAdapter(ptr ptr ptr ptr ptr long ptr ptr ptr long ptr)
+ @ stdcall NdisOpenConfiguration(ptr ptr ptr)
+ @ stdcall NdisOpenConfigurationKeyByIndex(ptr ptr long ptr ptr)
+ @ stdcall NdisOpenConfigurationKeyByName(ptr ptr ptr ptr)
+ @ stdcall NdisOpenFile(ptr ptr ptr ptr double)
+ @ stdcall NdisOpenProtocolConfiguration(ptr ptr ptr)
+ @ stdcall NdisOverrideBusNumber(ptr ptr long)
+ @ stdcall NdisPacketPoolUsage(ptr)
+ @ stdcall NdisPacketSize(long)
+ @ stdcall NdisPciAssignResources(ptr ptr ptr long ptr)
+ @ stdcall NdisQueryAdapterInstanceName(ptr ptr)
+ @ stdcall NdisQueryBindInstanceName(ptr ptr)
+ @ stdcall NdisQueryBuffer(ptr ptr ptr)
+ @ stdcall NdisQueryBufferOffset(ptr ptr ptr)
+ @ stdcall NdisQueryBufferSafe(ptr ptr ptr long)
+ @ stdcall NdisQueryMapRegisterCount(long ptr)
+ @ stdcall NdisQueryPendingIOCount(ptr ptr)
+ @ stdcall NdisReadConfiguration(ptr ptr ptr ptr long)
+ @ stdcall NdisReadEisaSlotInformation(ptr ptr ptr ptr)
+ @ stdcall NdisReadEisaSlotInformationEx(ptr ptr ptr ptr ptr)
+ @ stdcall NdisReadMcaPosInformation(ptr ptr ptr ptr)
+ @ stdcall NdisReadNetworkAddress(ptr ptr ptr ptr)
+ @ stdcall NdisReadPciSlotInformation(ptr long long ptr long)
+ @ stdcall NdisReadPcmciaAttributeMemory(ptr long ptr long)
+ @ stdcall NdisReEnumerateProtocolBindings(ptr)
+ @ stdcall NdisRegisterAdapter(ptr ptr ptr ptr ptr ptr)
+ @ stdcall NdisRegisterAdapterShutdownHandler(ptr ptr ptr)
+ @ stdcall NdisRegisterProtocol(ptr ptr ptr long)
+ @ stdcall NdisRegisterTdiCallBack(ptr ptr)
+ @ stdcall NdisReleaseAdapterResources(ptr)
+ @ stdcall NdisReleaseReadWriteLock(ptr ptr)
+ @ stdcall NdisReleaseSpinLock(ptr)
+ @ stdcall NdisRequest(ptr ptr ptr)
+ @ stdcall NdisReset(ptr ptr)
+ @ stdcall NdisResetEvent(ptr)
+ @ stdcall NdisReturnPackets(ptr long)
+ @ stdcall NdisSend(ptr ptr ptr)
+ @ stdcall NdisSendPackets(ptr ptr long)
+ @ stdcall NdisSetEvent(ptr)
+ @ stdcall NdisSetPacketCancelId(ptr ptr)
+ @ stdcall NdisSetPacketPoolProtocolId(ptr long)
+ @ stdcall NdisSetPacketStatus(ptr long ptr long)
+ @ stdcall NdisSetProtocolFilter(ptr ptr ptr ptr long long long ptr)
+ @ stdcall NdisSetTimer(ptr long)
+ @ stdcall NdisSetTimerEx(ptr long ptr)
+ @ stdcall NdisSetupDmaTransfer(ptr ptr ptr long long long)
+ @ stdcall NdisSystemProcessorCount()
+ @ stdcall NdisTerminateWrapper(ptr ptr)
+ @ stdcall NdisTransferData(ptr ptr ptr long long ptr ptr)
+ @ stdcall NdisUnchainBufferAtBack(ptr ptr)
+ @ stdcall NdisUnchainBufferAtFront(ptr ptr)
+ @ stdcall NdisUnicodeStringToAnsiString(ptr ptr)
+ @ stdcall NdisUnmapFile(ptr)
+ @ stdcall NdisUpcaseUnicodeString(ptr ptr)
+ @ stdcall NdisUpdateSharedMemory(ptr long ptr double)
+ @ stdcall NdisWaitEvent(ptr long)
+ @ stdcall NdisWriteConfiguration(ptr ptr ptr ptr)
+ @ cdecl NdisWriteErrorLogEntry(ptr long long)
+ @ stdcall NdisWriteEventLogEntry(ptr long long long ptr long ptr)
+ @ stdcall NdisWritePciSlotInformation(ptr long long ptr long)
+ @ stdcall NdisWritePcmciaAttributeMemory(ptr long ptr long)
+ @ stdcall TrFilterDprIndicateReceive(ptr ptr ptr long ptr long long)
+ @ stdcall TrFilterDprIndicateReceiveComplete(ptr)
+ @ stdcall NdisScheduleWorkItem(ptr)
index 2a9934c..daaf7ca 100644 (file)
@@ -1722,6 +1722,20 @@ NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter, PIRP Irp)
   return Status;
 }
 
+NTSTATUS
+NTAPI
+NdisICreateClose(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+  Irp->IoStatus.Status = STATUS_SUCCESS;
+  Irp->IoStatus.Information = 0;
+
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+  return STATUS_SUCCESS;
+}
+
 \f
 NTSTATUS
 NTAPI
@@ -2499,6 +2513,8 @@ NdisMRegisterMiniport(
 
   *MiniportPtr = Miniport;
 
+  Miniport->DriverObject->MajorFunction[IRP_MJ_CREATE] = NdisICreateClose;
+  Miniport->DriverObject->MajorFunction[IRP_MJ_CLOSE] = NdisICreateClose;
   Miniport->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp;
   Miniport->DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = NdisIShutdown;
   Miniport->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NdisIDeviceIoControl;
@@ -2960,6 +2976,12 @@ NdisMRegisterDevice(
 
     DriverBlock->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp;
 
+    if (!DriverBlock->DriverObject->MajorFunction[IRP_MJ_CREATE])
+        DriverBlock->DriverObject->MajorFunction[IRP_MJ_CREATE] = NdisICreateClose;
+
+    if (!DriverBlock->DriverObject->MajorFunction[IRP_MJ_CLOSE])
+        DriverBlock->DriverObject->MajorFunction[IRP_MJ_CLOSE] = NdisICreateClose;
+
     DeviceBlock->DeviceObject = DeviceObject;
     DeviceBlock->SymbolicName = SymbolicName;
 
diff --git a/drivers/network/tdi/misc/tdi.def b/drivers/network/tdi/misc/tdi.def
deleted file mode 100644 (file)
index 4f10551..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-; $Id$
-;
-; TDI.SYS Kernel Module - ReactOS Operating System
-;
-LIBRARY TDI.SYS
-
-EXPORTS
-CTEAllocateString@8
-CTEBlock@4
-CTEInitEvent@8
-CTEInitString@8
-CTEInitTimer@4
-CTEInitialize@0
-CTELogEvent@28
-CTEScheduleEvent@8
-CTESignal@8
-CTEStartTimer@16
-CTESystemUpTime@0
-TdiBuildNetbiosAddress@12
-TdiBuildNetbiosAddressEa@12
-TdiCopyBufferToMdl@24
-TdiCopyMdlToBuffer@24
-TdiDefaultChainedRcvDatagramHandler@40
-TdiDefaultChainedRcvExpeditedHandler@28
-TdiDefaultChainedReceiveHandler@28
-TdiDefaultConnectHandler@36
-TdiDefaultDisconnectHandler@28
-TdiDefaultErrorHandler@8
-TdiDefaultRcvDatagramHandler@44
-TdiDefaultRcvExpeditedHandler@32
-TdiDefaultReceiveHandler@32
-TdiDefaultSendPossibleHandler@12
-TdiDeregisterAddressChangeHandler@4
-TdiDeregisterDeviceObject@4
-TdiDeregisterNetAddress@4
-TdiDeregisterNotificationHandler@4
-TdiInitialize@4
-TdiMapBuffer@4
-TdiMapUserRequest@12
-TdiOpenNetbiosAddress@16
-TdiRegisterAddressChangeHandler@12
-TdiRegisterDeviceObject@8
-TdiRegisterNetAddress@8
-TdiRegisterNotificationHandler@12
-TdiReturnChainedReceives@8
-TdiUnmapBuffer@4
-; EOF
diff --git a/drivers/network/tdi/misc/tdi.spec b/drivers/network/tdi/misc/tdi.spec
new file mode 100644 (file)
index 0000000..a181064
--- /dev/null
@@ -0,0 +1,39 @@
+ @ stdcall CTEAllocateString(long long)
+ @ stdcall CTEBlock(long)
+ @ stdcall CTEInitEvent(long long)
+ @ stdcall CTEInitString(long long)
+ @ stdcall CTEInitTimer(long)
+ @ stdcall CTEInitialize()
+ @ stdcall CTELogEvent(long long long long long long long)
+ @ stdcall CTEScheduleEvent(long long)
+ @ stdcall CTESignal(long long)
+ @ stdcall CTEStartTimer(long long long long)
+ @ stdcall CTESystemUpTime()
+ @ stdcall TdiBuildNetbiosAddress(str long ptr)
+ @ stdcall TdiBuildNetbiosAddressEa(str long str)
+ @ stdcall TdiCopyBufferToMdl(ptr long long ptr long ptr)
+ @ stdcall TdiCopyMdlToBuffer(ptr long long ptr long ptr)
+ @ stdcall TdiDefaultChainedRcvDatagramHandler(ptr long ptr long ptr long long long ptr ptr)
+ @ stdcall TdiDefaultChainedRcvExpeditedHandler(ptr ptr long long long ptr ptr)
+ @ stdcall TdiDefaultChainedReceiveHandler(ptr ptr long long long ptr ptr)
+ @ stdcall TdiDefaultConnectHandler(ptr long ptr long ptr long ptr ptr ptr)
+ @ stdcall TdiDefaultDisconnectHandler(ptr ptr long ptr long ptr long)
+ @ stdcall TdiDefaultErrorHandler(ptr long)
+ @ stdcall TdiDefaultRcvDatagramHandler(ptr long ptr long ptr long long long ptr ptr ptr)
+ @ stdcall TdiDefaultRcvExpeditedHandler(ptr ptr long long long ptr ptr ptr)
+ @ stdcall TdiDefaultReceiveHandler(ptr ptr long long long ptr ptr ptr)
+ @ stdcall TdiDefaultSendPossibleHandler(ptr ptr long)
+ @ stdcall TdiDeregisterAddressChangeHandler(ptr)
+ @ stdcall TdiDeregisterDeviceObject(ptr)
+ @ stdcall TdiDeregisterNetAddress(ptr)
+ @ stdcall TdiDeregisterNotificationHandler(ptr)
+ @ stdcall TdiInitialize(ptr)
+ @ stdcall TdiMapBuffer(ptr)
+ @ stdcall TdiMapUserRequest(ptr ptr ptr)
+ @ stdcall TdiOpenNetbiosAddress(long long long long)
+ @ stdcall TdiRegisterAddressChangeHandler(long long long)
+ @ stdcall TdiRegisterDeviceObject(long long)
+ @ stdcall TdiRegisterNetAddress(long long)
+ @ stdcall TdiRegisterNotificationHandler(long long long)
+ @ stdcall TdiReturnChainedReceives(ptr long)
+ @ stdcall TdiUnmapBuffer(ptr)
index 3a7b059..1c658fa 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="tdi" type="kernelmodedriver" installbase="system32/drivers" installname="tdi.sys">
-       <importlibrary definition="misc/tdi.def"></importlibrary>
+       <importlibrary definition="misc/tdi.spec"></importlibrary>
        <library>ntoskrnl</library>
        <library>hal</library>
        <directory name="cte">
index e5a5149..ef46265 100644 (file)
@@ -5127,7 +5127,7 @@ Return Value:
         // The data buffer must be aligned.
         //
 
-        srb->DataBuffer = (PVOID) (((ULONG) (context + 1) + (alignment - 1)) &
+        srb->DataBuffer = (PVOID) (((ULONG_PTR) (context + 1) + (alignment - 1)) &
             ~(alignment - 1));
 
 
@@ -5877,7 +5877,7 @@ Return Value:
         irpStack = IoGetCurrentIrpStackLocation(irp);
 
         if (irpStack->Parameters.Others.Argument3) {
-            ULONG count;
+            ULONG_PTR count;
 
             //
             // Decrement the countdown timer and put the IRP back in the list.
@@ -6497,7 +6497,7 @@ Return Value:
     PIO_STACK_LOCATION  irpStack;
     NTSTATUS            status;
     BOOLEAN             retry;
-    ULONG               retryCount;
+    ULONG_PTR           retryCount;
     ULONG               lastSector;
     PIRP                originalIrp;
     PCDROM_DATA         cddata;
index 1ebe196..6a353bc 100644 (file)
@@ -2422,18 +2422,7 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
                                         0,
                                         &PhysicalDeviceObject);
         if (NT_SUCCESS(Status))
-        {
-            //
-            // ReactOS Fix
-            // The ReactOS Plug and Play Manager is broken and does not create
-            // the required keys when reporting a detected device.
-            // We hack around this ourselves.
-            //
-            RtlCreateUnicodeString(&((PEXTENDED_DEVOBJ_EXTENSION)
-                                   PhysicalDeviceObject->DeviceObjectExtension)
-                                   ->DeviceNode->InstancePath,
-                                   L"Root\\UNKNOWN\\0000");
-            
+        {            
             //
             // Create the device object
             //
index 1cace8b..fb2bb02 100644 (file)
@@ -537,10 +537,10 @@ WaitOnBaseBusy(
 {
     ULONG i;
     UCHAR Status;
-    for (i=0; i<200; i++) {
+    for (i=0; i<20000; i++) {
         GetBaseStatus(chan, Status);
         if (Status & IDE_STATUS_BUSY) {
-            AtapiStallExecution(10);
+            AtapiStallExecution(150);
             continue;
         } else {
             break;
@@ -640,11 +640,11 @@ WaitForDrq(
     for (i=0; i<1000; i++) {
         GetStatus(chan, Status);
         if (Status & IDE_STATUS_BUSY) {
-            AtapiStallExecution(10);
+            AtapiStallExecution(100);
         } else if (Status & IDE_STATUS_DRQ) {
             break;
         } else {
-            AtapiStallExecution(10);
+            AtapiStallExecution(200);
         }
     }
     return Status;
@@ -661,11 +661,11 @@ WaitShortForDrq(
     for (i=0; i<2; i++) {
         GetStatus(chan, Status);
         if (Status & IDE_STATUS_BUSY) {
-            AtapiStallExecution(10);
+            AtapiStallExecution(100);
         } else if (Status & IDE_STATUS_DRQ) {
             break;
         } else {
-            AtapiStallExecution(10);
+            AtapiStallExecution(100);
         }
     }
     return Status;
index 79ecbad..7ed7421 100644 (file)
@@ -11,8 +11,6 @@
 #include "usbehci.h"
 #include <wdmguid.h>
 #include <stdio.h>
-#define NDEBUG
-#include <debug.h>
 
 /* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
 
index b1ec550..c42ebfd 100644 (file)
 #include "usbehci.h"
 #include <stdio.h>
 
-//#include "ntstrsafe.h"
-
-VOID NTAPI
-DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context)
-{
-    PWORKITEM_DATA WorkItemData;
-    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
-
-    WorkItemData = (PWORKITEM_DATA)Context;
-    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
-    if (PdoDeviceExtension->CallbackRoutine)
-        PdoDeviceExtension->CallbackRoutine(PdoDeviceExtension->CallbackContext);
-    else
-        DPRINT1("PdoDeviceExtension->CallbackRoutine is NULL!\n");
-
-    IoFreeWorkItem(WorkItemData->IoWorkItem);
-    ExFreePool(WorkItemData);
-}
-
 VOID NTAPI
 EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
 {
@@ -60,7 +40,6 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
             /* Check for port change on this port */
             if (tmp & 0x02)
             {
-                PWORKITEM_DATA WorkItemData = NULL;
                 /* Connect or Disconnect? */
                 if (tmp & 0x01)
                 {
@@ -83,11 +62,11 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
                             DPRINT1("Releasing ownership to companion host controller!\n");
                             /* Release ownership to companion host controller */
                             WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), 0x4000);
+                            continue;
                         }
                     }
 
                     KeStallExecutionProcessor(30);
-                    DPRINT("port tmp %x\n", tmp);
 
                     /* As per USB 2.0 Specs, 9.1.2. Reset the port and clear the status change */
                     tmp |= 0x100 | 0x02;
@@ -100,17 +79,12 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
 
                     tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i)));
 
-                    GetDeviceDescriptor(FdoDeviceExtension, 0, 0, FALSE);
                     PdoDeviceExtension->ChildDeviceCount++;
-                    PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_HIGH_SPEED | USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE;
-                    WorkItemData = ExAllocatePool(NonPagedPool, sizeof(WORKITEM_DATA));
-                    if (!WorkItemData) ASSERT(FALSE);
-                    WorkItemData->IoWorkItem = IoAllocateWorkItem(PdoDeviceExtension->DeviceObject);
-                    WorkItemData->PdoDeviceExtension = PdoDeviceExtension;
-                    IoQueueWorkItem(WorkItemData->IoWorkItem,
-                                    (PIO_WORKITEM_ROUTINE)DeviceArrivalWorkItem,
-                                    DelayedWorkQueue,
-                                    WorkItemData);
+                    PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_HIGH_SPEED | USB_PORT_STATUS_CONNECT;
+                    PdoDeviceExtension->Ports[i].PortChange |= USB_PORT_STATUS_CONNECT;
+
+                    PdoDeviceExtension->HaltQueue = FALSE;
+                    KeSetEvent(&PdoDeviceExtension->QueueDrainedEvent, 0, FALSE);
                 }
                 else
                 {
@@ -545,6 +519,7 @@ StartDevice(PDEVICE_OBJECT DeviceObject, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PART
 
     StartEhci(DeviceObject);
     FdoDeviceExtension->DeviceState = DEVICESTARTED;
+
     return STATUS_SUCCESS;
 }
 
@@ -610,6 +585,10 @@ FdoQueryBusRelations(
     InitializeListHead(&PdoDeviceExtension->IrpQueue);
     KeInitializeSpinLock(&PdoDeviceExtension->IrpQueueLock);
 
+    KeInitializeEvent(&PdoDeviceExtension->QueueDrainedEvent, SynchronizationEvent, TRUE);
+
+    ExInitializeFastMutex(&PdoDeviceExtension->ListLock);
+
     Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
     DeviceExtension->Pdo = Pdo;
@@ -814,7 +793,6 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
         IoDetachDevice(FdoDeviceExtension->LowerDevice);
         IoDeleteSymbolicLink(&SymLinkName);
         IoDeleteDevice(Fdo);
-
         return STATUS_UNSUCCESSFUL;
     }
 
@@ -840,11 +818,14 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Unable to register device interface!\n");
+        ASSERT(FALSE);
     }
     else
     {
         Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
         DPRINT1("SetInterfaceState %x\n", Status);
+        if (!NT_SUCCESS(Status))
+            ASSERT(FALSE);
     }
     Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
index 06d7c50..99a601d 100644 (file)
@@ -62,26 +62,26 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
 
     KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
 
-    while(!IsListEmpty(&DeviceExtension->IrpQueue))
+    while (!IsListEmpty(&DeviceExtension->IrpQueue))
     {
         NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue);
         Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry);
 
         if (!Irp)
             break;
-
         Stack = IoGetCurrentIrpStackLocation(Irp);
         ASSERT(Stack);
 
         Urb = (PURB) Stack->Parameters.Others.Argument1;
+
         ASSERT(Urb);
 
         Information = 0;
         Status = STATUS_SUCCESS;
 
-        DPRINT1("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
-        DPRINT1("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
-        DPRINT1("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle);
+        DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
+        DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
+        DPRINT("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle);
 
         UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
         /* UsbdDeviceHandle of 0 is root hub */
@@ -97,14 +97,15 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
         {
             case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
             {
-                DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
-                DPRINT1("--->TransferBufferLength %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
-                DPRINT1("--->TransferBuffer %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
-                DPRINT1("--->PipeHandle %x\n",Urb->UrbBulkOrInterruptTransfer.PipeHandle);
-                DPRINT1("---->(PVOID)&UsbDevice->EndPointDescriptor %x\n", (PVOID)&UsbDevice->EndPointDescriptor);
-                DPRINT1("--->TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags);
-
+                DPRINT("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
+                DPRINT("--->TransferBufferLength %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
+                DPRINT("--->TransferBuffer %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
+                DPRINT("--->PipeHandle %x\n",Urb->UrbBulkOrInterruptTransfer.PipeHandle);
+                DPRINT("---->(PVOID)&UsbDevice->EndPointDescriptor %x\n", (PVOID)&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor);
+                DPRINT("--->TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags);
+                ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
                 RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
+
                 if (UsbDevice == DeviceExtension->UsbDevices[0])
                 {
                     if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
@@ -112,10 +113,13 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                         LONG i;
                         for (i = 0; i < 8; i++)
                         {
+                            if (i == 0){
+                            DPRINT("PortStatus %x\n", DeviceExtension->Ports[i].PortStatus);
+                            DPRINT("PortChange %x\n", DeviceExtension->Ports[i].PortChange);}
                             if (DeviceExtension->Ports[i].PortChange)
                             {
                                 DPRINT1("Inform hub driver that port %d has changed\n", i+1);
-                                ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << (i + 1);
+                                ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7);
                             }
                         }
                     }
@@ -123,8 +127,11 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                     {
                         Urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER;
                         Status = STATUS_UNSUCCESSFUL;
+                        DPRINT1("Invalid transfer flags for SCE\n");
                     }
                 }
+                else
+                    DPRINT1("Interrupt Transfer not for hub\n");
                 break;
             }
             case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
@@ -132,9 +139,9 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                 DPRINT("Get Status from Device\n");
                 DPRINT("Index : %d\n", Urb->UrbControlGetStatusRequest.Index);
 
-                /* Copied from pvdrivers */
                 if (Urb->UrbControlGetStatusRequest.Index == 0)
                 {
+                    ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
                     *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer = USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE;
                 }
                 else
@@ -156,7 +163,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                         {
                             Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
                         }
-
+                        ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer != NULL);
                         RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
                                       &UsbDevice->DeviceDescriptor,
                                       Urb->UrbControlDescriptorRequest.TransferBufferLength);
@@ -164,19 +171,40 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                     }
                     case USB_CONFIGURATION_DESCRIPTOR_TYPE:
                     {
+                        PUCHAR BufPtr;
+                        LONG i, j;
+
                         DPRINT1("USB CONFIG DESC\n");
-                        ULONG FullDescriptorLength = sizeof(USB_CONFIGURATION_DESCRIPTOR) +
-                                                     sizeof(USB_INTERFACE_DESCRIPTOR) +
-                                                     sizeof(USB_ENDPOINT_DESCRIPTOR);
 
-                        if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= FullDescriptorLength)
+                        if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength)
+                        {
+                            Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength;
+                        }
+                        else
                         {
-                            Urb->UrbControlDescriptorRequest.TransferBufferLength = FullDescriptorLength;
+                            DPRINT1("Buffer to small!!!\n");
+                            //ASSERT(FALSE);
+                        }
+
+                        ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
+                        BufPtr = (PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer;
+
+                        /* Copy the Configuration Descriptor */
+                        RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
+                        BufPtr += sizeof(USB_CONFIGURATION_DESCRIPTOR);
+                        for (i = 0; i < UsbDevice->ActiveConfig->ConfigurationDescriptor.bNumInterfaces; i++)
+                        {
+                            /* Copy the Interface Descriptor */
+                            RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
+                            BufPtr += sizeof(USB_INTERFACE_DESCRIPTOR);
+                            for (j = 0; j < UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor.bNumEndpoints; j++)
+                            {
+                                /* Copy the EndPoint Descriptor */
+                                RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->EndPoints[j]->EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
+                                BufPtr += sizeof(USB_ENDPOINT_DESCRIPTOR);
+                            }
                         }
 
-                        RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
-                                      &UsbDevice->ConfigurationDescriptor,
-                                      Urb->UrbControlDescriptorRequest.TransferBufferLength);
                         break;
                     }
                     case USB_STRING_DESCRIPTOR_TYPE:
@@ -213,7 +241,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                     DPRINT(" MaxPower = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->MaxPower);
 
 
-                    Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&DeviceExtension->UsbDevices[0]->ConfigurationDescriptor;
+                    Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&DeviceExtension->UsbDevices[0]->ActiveConfig->ConfigurationDescriptor;
                     DPRINT("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle);
                     InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
 
@@ -229,10 +257,10 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                         DPRINT(" Reserved = %02x\n", (ULONG)InterfaceInfo->Reserved);
                         DPRINT(" InterfaceHandle = %p\n", InterfaceInfo->InterfaceHandle);
                         DPRINT(" NumberOfPipes = %d\n", InterfaceInfo->NumberOfPipes);
-                        InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->InterfaceDescriptor;
-                        InterfaceInfo->Class = UsbDevice->InterfaceDescriptor.bInterfaceClass;
-                        InterfaceInfo->SubClass = UsbDevice->InterfaceDescriptor.bInterfaceSubClass;
-                        InterfaceInfo->Protocol = UsbDevice->InterfaceDescriptor.bInterfaceProtocol;
+                        InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->ActiveInterface->InterfaceDescriptor;
+                        InterfaceInfo->Class = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceClass;
+                        InterfaceInfo->SubClass = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceSubClass;
+                        InterfaceInfo->Protocol = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceProtocol;
                         InterfaceInfo->Reserved = 0;
 
                         for (pCount = 0; pCount < InterfaceInfo->NumberOfPipes; pCount++)
@@ -245,11 +273,11 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                           DPRINT(" PipeHandle = %x\n", InterfaceInfo->Pipes[pCount].PipeHandle);
                           DPRINT(" MaximumTransferSize = %d\n", InterfaceInfo->Pipes[pCount].MaximumTransferSize);
                           DPRINT(" PipeFlags = %08x\n", InterfaceInfo->Pipes[pCount].PipeFlags);
-                          InterfaceInfo->Pipes[pCount].MaximumPacketSize = UsbDevice->EndPointDescriptor.wMaxPacketSize;
-                          InterfaceInfo->Pipes[pCount].EndpointAddress = UsbDevice->EndPointDescriptor.bEndpointAddress;
-                          InterfaceInfo->Pipes[pCount].Interval = UsbDevice->EndPointDescriptor.bInterval;
+                          InterfaceInfo->Pipes[pCount].MaximumPacketSize = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.wMaxPacketSize;
+                          InterfaceInfo->Pipes[pCount].EndpointAddress = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bEndpointAddress;
+                          InterfaceInfo->Pipes[pCount].Interval = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bInterval;
                           InterfaceInfo->Pipes[pCount].PipeType = UsbdPipeTypeInterrupt;
-                          InterfaceInfo->Pipes[pCount].PipeHandle = (PVOID)&UsbDevice->EndPointDescriptor;
+                          InterfaceInfo->Pipes[pCount].PipeHandle = (PVOID)&UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor;
                           if (InterfaceInfo->Pipes[pCount].MaximumTransferSize == 0)
                               InterfaceInfo->Pipes[pCount].MaximumTransferSize = 4096;
                           /* InterfaceInfo->Pipes[j].PipeFlags = 0; */
@@ -315,9 +343,12 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                                break;
                             }
                             case USB_DEVICE_CLASS_RESERVED:
+                                DPRINT1("Reserved!!!\n");
                             case USB_DEVICE_CLASS_HUB:
                             {
+
                                 PUSB_HUB_DESCRIPTOR UsbHubDescr = Urb->UrbControlVendorClassRequest.TransferBuffer;
+                                ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
                                 /* FIXME: Handle more than root hub? */
                                 if(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR))
                                 {
@@ -328,7 +359,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                                     /* FIXME: Handle this correctly */
                                     UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
                                     UsbHubDescr->bDescriptorType = 0x29;
-                                    return;
+                                    break;
                                 }
                                 DPRINT1("USB_DEVICE_CLASS_HUB request\n");
                                 UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
@@ -355,6 +386,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
 
                         if (Urb->UrbControlVendorClassRequest.Index == 1)
                         {
+                            ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
                             ((PULONG)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0;
                         }
                         break;
@@ -374,7 +406,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                     case USB_REQUEST_GET_STATUS:
                     {
                         DPRINT1("OTHER: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index);
-
+                        ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
                         ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus;
                         ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange;
                         break;
@@ -425,7 +457,6 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                     case USB_REQUEST_SET_ADDRESS:
                     {
                         DPRINT1("USB_REQUEST_SET_ADDRESS\n");
-                        ASSERT(FALSE);
                         break;
                     }
                     case USB_REQUEST_GET_DESCRIPTOR:
@@ -466,7 +497,6 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                     default:
                     {
                         DPRINT1("Unknown Function Class Unknown request\n");
-                        ASSERT(FALSE);
                         break;
                     }
                 }
@@ -476,13 +506,10 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
             {
                 DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function);
                 Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
-                ASSERT(FALSE);
             }
 
         }
 
-        KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
-
         Irp->IoStatus.Status = Status;
         Irp->IoStatus.Information = Information;
 
@@ -493,10 +520,16 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
             Urb->UrbHeader.UsbdFlags = 0;
         }
 
+        KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
+
+        if (DeviceExtension->HaltQueue)
+            break;
     }
 
     KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
+    if (!DeviceExtension->HaltQueue)
+        KeSetEvent(&DeviceExtension->QueueDrainedEvent, 0, FALSE);
 }
 
index 6a0d735..cf84911 100644 (file)
@@ -8,11 +8,12 @@
  */
 
 #define INITGUID
-#define NDEBUG
 
 #include "usbehci.h"
-#include <wdmguid.h>
+#include <hubbusif.h>
+#include <usbbusif.h>
 #include "usbiffn.h"
+#include <wdmguid.h>
 #include <stdio.h>
 #include <debug.h>
 
@@ -51,8 +52,11 @@ const UCHAR ROOTHUB2_CONFIGURATION_DESCRIPTOR [] =
         6: Self-powered,
         5: Remote wakeup,
         4..0: reserved */
-    0x00,       /* MaxPower; */
+    0x00       /* MaxPower; */
+};
 
+const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR [] = 
+{
     /* one interface */
     0x09,       /* bLength: Interface; */
     0x04,       /* bDescriptorType; Interface */
@@ -62,8 +66,11 @@ const UCHAR ROOTHUB2_CONFIGURATION_DESCRIPTOR [] =
     0x09,       /* bInterfaceClass; HUB_CLASSCODE */
     0x01,       /* bInterfaceSubClass; */
     0x00,       /* bInterfaceProtocol: */
-    0x00,       /* iInterface; */
+    0x00       /* iInterface; */
+};
 
+const UCHAR ROOTHUB2_ENDPOINT_DESCRIPTOR [] =
+{
     /* one endpoint (status change endpoint) */
     0x07,       /* bLength; */
     0x05,       /* bDescriptorType; Endpoint */
@@ -78,38 +85,24 @@ VOID NTAPI
 UrbWorkerThread(PVOID Context)
 {
     PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Context;
+    NTSTATUS Status;
+    LARGE_INTEGER DueTime;
+    PVOID PollEvents[] = { (PVOID) &PdoDeviceExtension->QueueDrainedEvent, (PVOID) &PdoDeviceExtension->Timer };
 
-    while (PdoDeviceExtension->HaltUrbHandling == FALSE)
-    {
-        CompletePendingURBRequest(PdoDeviceExtension);
-        KeStallExecutionProcessor(10);
-    }
-    DPRINT1("Thread terminated\n");
-}
+    DueTime.QuadPart = 0;
+    KeInitializeTimerEx(&PdoDeviceExtension->Timer, SynchronizationTimer);
+    KeSetTimerEx(&PdoDeviceExtension->Timer, DueTime, 100, NULL);
 
-/* FIXME: Do something better */
-PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub)
-{
-    PUSB_DEVICE UsbDevicePointer = NULL;
-    UsbDevicePointer = ExAllocatePool(NonPagedPool, sizeof(USB_DEVICE));
-    if (!UsbDevicePointer)
+    while (TRUE)
     {
-        DPRINT1("Out of memory\n");
-        return NULL;
-    }
+        Status = KeWaitForMultipleObjects(2, PollEvents, WaitAll, Executive, KernelMode, FALSE, NULL, NULL);
 
-    if ((Hub) && (!Parent))
-    {
-        DPRINT1("This is the root hub\n");
+        if (!PdoDeviceExtension->HaltQueue)
+            KeResetEvent(&PdoDeviceExtension->QueueDrainedEvent);
+        CompletePendingURBRequest(PdoDeviceExtension);
     }
 
-    UsbDevicePointer->Address = DeviceNumber;
-    UsbDevicePointer->Port = Port;
-    UsbDevicePointer->ParentDevice = Parent;
-
-    UsbDevicePointer->IsHub = Hub;
-
-    return UsbDevicePointer;
+    DPRINT1("Thread terminated\n");
 }
 
 NTSTATUS NTAPI
@@ -137,7 +130,6 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
             Urb = (PURB) Stack->Parameters.Others.Argument1;
             DPRINT("Header Length %d\n", Urb->UrbHeader.Length);
             DPRINT("Header Function %d\n", Urb->UrbHeader.Function);
-
             /* Queue all request for now, kernel thread will complete them */
             QueueURBRequest(PdoDeviceExtension, Irp);
             Information = 0;
@@ -153,6 +145,8 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
         case IOCTL_INTERNAL_USB_ENABLE_PORT:
         {
             DPRINT1("IOCTL_INTERNAL_USB_ENABLE_PORT\n");
+            Information = 0;
+            Status = STATUS_SUCCESS;
             break;
         }
         case IOCTL_INTERNAL_USB_GET_BUS_INFO:
@@ -176,21 +170,27 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
             if (Stack->Parameters.Others.Argument1)
             {
                 /* Return the root hubs devicehandle */
+                DPRINT1("Returning RootHub Handle %x\n", PdoDeviceExtension->UsbDevices[0]);
                 *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)PdoDeviceExtension->UsbDevices[0];
+                Status = STATUS_SUCCESS;
             }
             else
                 Status = STATUS_INVALID_DEVICE_REQUEST;
+
             break;
+
         }
         case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
         {
             DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n", IOCTL_INTERNAL_USB_GET_HUB_COUNT);
+            ASSERT(Stack->Parameters.Others.Argument1 != NULL);
             if (Stack->Parameters.Others.Argument1)
             {
                 /* FIXME: Determine the number of hubs between the usb device and root hub */
-                /* For now return 1, the root hub */
-                *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)1;
+                DPRINT1("RootHubCount %x\n", *(PULONG)Stack->Parameters.Others.Argument1);
+                *(PULONG)Stack->Parameters.Others.Argument1 = 0;
             }
+            Status = STATUS_SUCCESS;
             break;
         }
         case IOCTL_INTERNAL_USB_GET_HUB_NAME:
@@ -220,7 +220,7 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
             if (Stack->Parameters.Others.Argument1)
                 *(PVOID *)Stack->Parameters.Others.Argument1 = FdoDeviceExtension->Pdo;
             if (Stack->Parameters.Others.Argument2)
-                *(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDevice(FdoDeviceExtension->DeviceObject);
+                *(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDeviceReference(FdoDeviceExtension->DeviceObject);
 
             Information = 0;
             Status = STATUS_SUCCESS;
@@ -228,7 +228,18 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
         }
         case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
         {
+            PUSB_IDLE_CALLBACK_INFO CallBackInfo;
             DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
+            /* FIXME: Set Callback for safe power down */
+            CallBackInfo = Stack->Parameters.DeviceIoControl.Type3InputBuffer;
+            DPRINT1("IdleCallback %x\n", CallBackInfo->IdleCallback);
+            DPRINT1("IdleContext %x\n", CallBackInfo->IdleContext);
+
+            PdoDeviceExtension->IdleCallback = CallBackInfo->IdleCallback;
+            PdoDeviceExtension->IdleContext = CallBackInfo->IdleContext;
+
+            Information = 0;
+            Status = STATUS_SUCCESS;
             break;
         }
         default:
@@ -275,6 +286,7 @@ PdoQueryId(PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG_PTR* Information)
             SourceString.Length = SourceString.MaximumLength = Index * sizeof(WCHAR);
             SourceString.Buffer = Buffer;
             break;
+
         }
         case BusQueryCompatibleIDs:
         {
@@ -375,13 +387,45 @@ PdoDispatchPnp(
             RootHubDevice->DeviceDescriptor.idVendor = FdoDeviceExtension->VendorId;
             RootHubDevice->DeviceDescriptor.idProduct = FdoDeviceExtension->DeviceId;
 
-            RtlCopyMemory(&RootHubDevice->ConfigurationDescriptor,
+            /* FIXME: Do something better below */
+
+            RootHubDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
+                                                            sizeof(PVOID) * RootHubDevice->DeviceDescriptor.bNumConfigurations,
+                                                            USB_POOL_TAG);
+
+            RootHubDevice->Configs[0] = ExAllocatePoolWithTag(NonPagedPool,
+                                                            sizeof(USB_CONFIGURATION) + sizeof(PVOID) * ROOTHUB2_CONFIGURATION_DESCRIPTOR[5],
+                                                            USB_POOL_TAG);
+
+            RootHubDevice->Configs[0]->Interfaces[0] = ExAllocatePoolWithTag(NonPagedPool,
+                                                            sizeof(USB_INTERFACE) + sizeof(PVOID) * ROOTHUB2_INTERFACE_DESCRIPTOR[3],
+                                                            USB_POOL_TAG);
+
+            RootHubDevice->Configs[0]->Interfaces[0]->EndPoints[0] = ExAllocatePoolWithTag(NonPagedPool,
+                                                            sizeof(USB_ENDPOINT),
+                                                            USB_POOL_TAG);
+
+            RootHubDevice->ActiveConfig = RootHubDevice->Configs[0];
+            RootHubDevice->ActiveInterface = RootHubDevice->ActiveConfig->Interfaces[0];
+
+            RtlCopyMemory(&RootHubDevice->ActiveConfig->ConfigurationDescriptor,
                           ROOTHUB2_CONFIGURATION_DESCRIPTOR,
                           sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR));
 
+            RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->InterfaceDescriptor,
+                         ROOTHUB2_INTERFACE_DESCRIPTOR,
+                         sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR));
+
+            RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->EndPoints[0]->EndPointDescriptor,
+                         ROOTHUB2_ENDPOINT_DESCRIPTOR,
+                         sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR));
+            RootHubDevice->DeviceSpeed = UsbHighSpeed;
+            RootHubDevice->DeviceType = Usb20Device;
+
             PdoDeviceExtension->UsbDevices[0] = RootHubDevice;
 
             /* Create a thread to handle the URB's */
+
             Status = PsCreateSystemThread(&PdoDeviceExtension->ThreadHandle,
                                           THREAD_ALL_ACCESS,
                                           NULL,
@@ -397,14 +441,16 @@ PdoDispatchPnp(
             if (!NT_SUCCESS(Status))
             {
                 DPRINT1("Failed to register interface\n");
+                ASSERT(FALSE);
             }
             else
             {
                 Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
                 DPRINT1("Set interface state %x\n", Status);
+                if (!NT_SUCCESS(Status)) 
+                    ASSERT(FALSE);
             }
 
-
             Status = STATUS_SUCCESS;
             break;
         }
@@ -420,7 +466,19 @@ PdoDispatchPnp(
                     break;
                 }
                 case BusRelations:
+                {
+                    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+                    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
                     DPRINT1("BusRelations!!!!!\n");
+
+                    /* The hub driver has created the new device object and reported to pnp, as a result the pnp manager
+                       has resent this IRP and type, so leave the next SCE request pending until a new device arrives.
+                       Is there a better way to do this */
+                    ExAcquireFastMutex(&PdoDeviceExtension->ListLock);
+                    PdoDeviceExtension->HaltQueue = TRUE;
+                    ExReleaseFastMutex(&PdoDeviceExtension->ListLock);
+                }
                 case RemovalRelations:
                 case EjectionRelations:
                 {
@@ -500,62 +558,101 @@ PdoDispatchPnp(
             {
                 DPRINT1("Failed to create string from GUID!\n");
             }
-            DPRINT1("Interface GUID requested %wZ\n", &GuidString);
-            DPRINT1("QueryInterface.Size %x\n", Stack->Parameters.QueryInterface.Size);
-            DPRINT1("QueryInterface.Version %x\n", Stack->Parameters.QueryInterface.Version);
 
+            DPRINT("Interface GUID requested %wZ\n", &GuidString);
+            DPRINT("QueryInterface.Size %x\n", Stack->Parameters.QueryInterface.Size);
+            DPRINT("QueryInterface.Version %x\n", Stack->Parameters.QueryInterface.Version);
+
+            /* Assume success */
             Status = STATUS_SUCCESS;
             Information = 0;
 
-            /* FIXME: Check the actual Guid */
-            if (Stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V2) && (Stack->Parameters.QueryInterface.Version == 2))
-            {
-                InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) Stack->Parameters.QueryInterface.Interface;
-                InterfaceDI->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
-                InterfaceDI->Version = 2;
-                InterfaceDI->BusContext = PdoDeviceExtension->DeviceObject;
-                InterfaceDI->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
-                InterfaceDI->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
-                InterfaceDI->GetUSBDIVersion = GetUSBDIVersion;
-                InterfaceDI->QueryBusTime = QueryBusTime;
-                InterfaceDI->SubmitIsoOutUrb = SubmitIsoOutUrb;
-                InterfaceDI->QueryBusInformation = QueryBusInformation;
-                InterfaceDI->IsDeviceHighSpeed = IsDeviceHighSpeed;
-                InterfaceDI->EnumLogEntry = EnumLogEntry;
-            }
-            /* FIXME: Check the actual Guid */
-            else if (Stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_HUB_V5) &&
-                    (Stack->Parameters.QueryInterface.Version == 5))
+            if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID))
             {
                 InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)Stack->Parameters.QueryInterface.Interface;
-                InterfaceHub->Version = 5;
-                InterfaceHub->Size = sizeof(USB_BUS_INTERFACE_HUB_V5);
-                InterfaceHub->BusContext = PdoDeviceExtension->DeviceObject;
-                InterfaceHub->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
-                InterfaceHub->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
-                InterfaceHub->CreateUsbDevice = CreateUsbDevice;
-                InterfaceHub->InitializeUsbDevice = InitializeUsbDevice;
-                InterfaceHub->GetUsbDescriptors = GetUsbDescriptors;
-                InterfaceHub->RemoveUsbDevice = RemoveUsbDevice;
-                InterfaceHub->RestoreUsbDevice = RestoreUsbDevice;
-                InterfaceHub->GetPortHackFlags = GetPortHackFlags;
-                InterfaceHub->QueryDeviceInformation = QueryDeviceInformation;
-                InterfaceHub->GetControllerInformation = GetControllerInformation;
-                InterfaceHub->ControllerSelectiveSuspend = ControllerSelectiveSuspend;
-                InterfaceHub->GetExtendedHubInformation = GetExtendedHubInformation;
-                InterfaceHub->GetRootHubSymbolicName = GetRootHubSymbolicName;
-                InterfaceHub->GetDeviceBusContext = GetDeviceBusContext;
-                InterfaceHub->Initialize20Hub = Initialize20Hub;
-                InterfaceHub->RootHubInitNotification = RootHubInitNotification;
-                InterfaceHub->FlushTransfers = FlushTransfers;
-                InterfaceHub->SetDeviceHandleData = SetDeviceHandleData;
+                InterfaceHub->Version = Stack->Parameters.QueryInterface.Version;
+                if (Stack->Parameters.QueryInterface.Version >= 0)
+                {
+                    InterfaceHub->Size = Stack->Parameters.QueryInterface.Size;
+                    InterfaceHub->BusContext = PdoDeviceExtension->DeviceObject;
+                    InterfaceHub->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
+                    InterfaceHub->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
+                }
+                if (Stack->Parameters.QueryInterface.Version >= 1)
+                {
+                    InterfaceHub->CreateUsbDevice = CreateUsbDevice;
+                    InterfaceHub->InitializeUsbDevice = InitializeUsbDevice;
+                    InterfaceHub->GetUsbDescriptors = GetUsbDescriptors;
+                    InterfaceHub->RemoveUsbDevice = RemoveUsbDevice;
+                    InterfaceHub->RestoreUsbDevice = RestoreUsbDevice;
+                    InterfaceHub->GetPortHackFlags = GetPortHackFlags;
+                    InterfaceHub->QueryDeviceInformation = QueryDeviceInformation;
+                }
+                if (Stack->Parameters.QueryInterface.Version >= 2)
+                {
+                    InterfaceHub->GetControllerInformation = GetControllerInformation;
+                    InterfaceHub->ControllerSelectiveSuspend = ControllerSelectiveSuspend;
+                    InterfaceHub->GetExtendedHubInformation = GetExtendedHubInformation;
+                    InterfaceHub->GetRootHubSymbolicName = GetRootHubSymbolicName;
+                    InterfaceHub->GetDeviceBusContext = GetDeviceBusContext;
+                    InterfaceHub->Initialize20Hub = Initialize20Hub;
+
+                }
+                if (Stack->Parameters.QueryInterface.Version >= 3)
+                {
+                    InterfaceHub->RootHubInitNotification = RootHubInitNotification;
+                }
+                if (Stack->Parameters.QueryInterface.Version >= 4)
+                {
+                    InterfaceHub->FlushTransfers = FlushTransfers;
+                }
+                if (Stack->Parameters.QueryInterface.Version >= 5)
+                {
+                    InterfaceHub->SetDeviceHandleData = SetDeviceHandleData;
+                }
+                if (Stack->Parameters.QueryInterface.Version >= 6)
+                {
+                    DPRINT1("USB_BUS_INTERFACE_HUB_GUID version not supported!\n");
+                }
+                break;
             }
-            else
+
+            if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID))
             {
-                DPRINT1("Not Supported\n");
-                Status = Irp->IoStatus.Status;
-                Information = Irp->IoStatus.Information;
+                InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) Stack->Parameters.QueryInterface.Interface;
+                InterfaceDI->Version = Stack->Parameters.QueryInterface.Version;
+                if (Stack->Parameters.QueryInterface.Version >= 0)
+                {
+                    //InterfaceDI->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
+                    InterfaceDI->Size = Stack->Parameters.QueryInterface.Size;
+                    InterfaceDI->BusContext = PdoDeviceExtension->DeviceObject;
+                    InterfaceDI->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
+                    InterfaceDI->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
+                    InterfaceDI->GetUSBDIVersion = GetUSBDIVersion;
+                    InterfaceDI->QueryBusTime = QueryBusTime;
+                    InterfaceDI->SubmitIsoOutUrb = SubmitIsoOutUrb;
+                    InterfaceDI->QueryBusInformation = QueryBusInformation;
+                }
+                if (Stack->Parameters.QueryInterface.Version >= 1)
+                {
+                    InterfaceDI->IsDeviceHighSpeed = IsDeviceHighSpeed;
+                }
+                if (Stack->Parameters.QueryInterface.Version >= 2)
+                {
+                    InterfaceDI->EnumLogEntry = EnumLogEntry;
+                }
+
+                if (Stack->Parameters.QueryInterface.Version >= 3)
+                {
+                    DPRINT1("SB_BUS_INTERFACE_USBDI_GUID version not supported!\n");
+                }
+                break;
             }
+
+            DPRINT1("GUID Not Supported\n");
+            Status = Irp->IoStatus.Status;
+            Information = Irp->IoStatus.Information;
+
             break;
         }
         case IRP_MN_QUERY_BUS_INFORMATION:
@@ -593,4 +690,3 @@ PdoDispatchPnp(
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return Status;
 }
-
index d9a85ba..cbd1845 100644 (file)
@@ -15,7 +15,7 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead,
                                            PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD1,
                                            PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD2,
                                            PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD3,
-                                           PEHCI_SETUP_FORMAT *CtrlSetup,
+                                           PUSB_DEFAULT_PIPE_SETUP_PACKET *CtrlSetup,
                                            PVOID *CtrlData,
                                            ULONG Size)
 {
@@ -67,15 +67,15 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead,
     *CtrlTD3 = (PQUEUE_TRANSFER_DESCRIPTOR) (((ULONG)(*CtrlTD2) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0x1F) & ~0x1F);
 
     /* Must be Page aligned */
-    *CtrlSetup = (PEHCI_SETUP_FORMAT) (( (ULONG)(*CtrlTD3) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0xFFF)  & ~0xFFF);
-    *CtrlData = (PUSB_DEVICE_DESCRIPTOR) (( (ULONG)(*CtrlSetup) + sizeof(EHCI_SETUP_FORMAT) + 0xFFF)  & ~0xFFF);
+    *CtrlSetup = (PUSB_DEFAULT_PIPE_SETUP_PACKET) (( (ULONG)(*CtrlTD3) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0xFFF)  & ~0xFFF);
+    *CtrlData = (PVOID) (( (ULONG)(*CtrlSetup) + sizeof(USB_DEFAULT_PIPE_SETUP_PACKET) + 0xFFF)  & ~0xFFF);
 
     (*CtrlTD1)->NextPointer = TERMINATE_POINTER;
     (*CtrlTD1)->AlternateNextPointer = TERMINATE_POINTER;
     (*CtrlTD1)->BufferPointer[0] = (ULONG)MmGetPhysicalAddress((PVOID) (*CtrlSetup)).LowPart;
     (*CtrlTD1)->Token.Bits.DataToggle = FALSE;
     (*CtrlTD1)->Token.Bits.InterruptOnComplete = FALSE;
-    (*CtrlTD1)->Token.Bits.TotalBytesToTransfer = sizeof(EHCI_SETUP_FORMAT);
+    (*CtrlTD1)->Token.Bits.TotalBytesToTransfer = sizeof(USB_DEFAULT_PIPE_SETUP_PACKET);
     (*CtrlTD1)->Token.Bits.ErrorCounter = 0x03;
     (*CtrlTD1)->Token.Bits.PIDCode = PID_CODE_SETUP_TOKEN;
     (*CtrlTD1)->Token.Bits.Active = TRUE;
@@ -105,46 +105,48 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead,
 }
 
 BOOLEAN
-GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEVICE_DESCRIPTOR OutBuffer, BOOLEAN Hub)
+ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, UCHAR Address, ULONG Port, PVOID Buffer, ULONG BufferLength)
 {
-    PEHCI_SETUP_FORMAT CtrlSetup = NULL;
-    PUSB_DEVICE_DESCRIPTOR CtrlData = NULL;
+    PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup = NULL;
+    PVOID CtrlData = NULL;
     PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL;
     PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL;
     PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL;
+
     PQUEUE_HEAD QueueHead;
     PEHCI_USBCMD_CONTENT UsbCmd;
     PEHCI_USBSTS_CONTEXT UsbSts;
     LONG Base;
     LONG tmp;
 
+    DPRINT1("ExecuteControlRequest: Buffer %x, Length %x\n", Buffer, BufferLength);
+
     Base = (ULONG) DeviceExtension->ResourceMemory;
 
     /* Set up the QUEUE HEAD in memory */
     QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr);
 
+    /* Initialize the memory pointers */
     IntializeHeadQueueForStandardRequest(QueueHead,
                                          &CtrlTD1,
                                          &CtrlTD2,
                                          &CtrlTD3,
                                          &CtrlSetup,
                                          (PVOID)&CtrlData,
-                                         sizeof(USB_DEVICE_DESCRIPTOR));
+                                         BufferLength);
 
-    /* FIXME: Use defines and handle other than Device Desciptors */
-    if (Hub)
-    {
-        CtrlSetup->bmRequestType = 0x80;
-        CtrlSetup->wValue = 0x0600;
-    }
-    else
-    {
-        CtrlSetup->bmRequestType = 0x80;
-        CtrlSetup->wValue = 0x0100;
-    }
-    CtrlSetup->bRequest = 0x06;
-    CtrlSetup->wIndex = 0;
-    CtrlSetup->wLength = sizeof(USB_DEVICE_DESCRIPTOR);
+    CtrlSetup->bmRequestType._BM.Recipient = SetupPacket->bmRequestType._BM.Recipient;
+    CtrlSetup->bmRequestType._BM.Type = SetupPacket->bmRequestType._BM.Type;
+    CtrlSetup->bmRequestType._BM.Dir = SetupPacket->bmRequestType._BM.Dir;
+    CtrlSetup->bRequest = SetupPacket->bRequest;
+    CtrlSetup->wValue.LowByte = SetupPacket->wValue.LowByte;
+    CtrlSetup->wValue.HiByte = SetupPacket->wValue.HiByte;
+    CtrlSetup->wIndex.W = SetupPacket->wIndex.W;
+    CtrlSetup->wLength = SetupPacket->wLength;
+
+
+    QueueHead->EndPointCapabilities1.DeviceAddress = Address;
+    //QueueHead->EndPointCapabilities2.PortNumber = Port;
 
     tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
     UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
@@ -190,136 +192,15 @@ GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEV
             break;
     }
 
-    if (OutBuffer != NULL)
-    {
-        OutBuffer->bLength = CtrlData->bLength;
-        OutBuffer->bDescriptorType = CtrlData->bDescriptorType;
-        OutBuffer->bcdUSB = CtrlData->bcdUSB;
-        OutBuffer->bDeviceClass = CtrlData->bDeviceClass;
-        OutBuffer->bDeviceSubClass = CtrlData->bDeviceSubClass;
-        OutBuffer->bDeviceProtocol = CtrlData->bDeviceProtocol;
-        OutBuffer->bMaxPacketSize0 = CtrlData->bMaxPacketSize0;
-        OutBuffer->idVendor = CtrlData->idVendor;
-        OutBuffer->idProduct = CtrlData->idProduct;
-        OutBuffer->bcdDevice = CtrlData->bcdDevice;
-        OutBuffer->iManufacturer = CtrlData->iManufacturer;
-        OutBuffer->iProduct = CtrlData->iProduct;
-        OutBuffer->iSerialNumber = CtrlData->iSerialNumber;
-        OutBuffer->bNumConfigurations = CtrlData->bNumConfigurations;
-    }
-
-    DPRINT1("bLength %d\n", CtrlData->bLength);
-    DPRINT1("bDescriptorType %x\n", CtrlData->bDescriptorType);
-    DPRINT1("bcdUSB %x\n", CtrlData->bcdUSB);
-    DPRINT1("CtrlData->bDeviceClass %x\n", CtrlData->bDeviceClass);
-    DPRINT1("CtrlData->bDeviceSubClass %x\n", CtrlData->bDeviceSubClass);
-    DPRINT1("CtrlData->bDeviceProtocal %x\n", CtrlData->bDeviceProtocol);
-    DPRINT1("CtrlData->bMaxPacketSize %x\n", CtrlData->bMaxPacketSize0);
-    DPRINT1("CtrlData->idVendor %x\n", CtrlData->idVendor);
-    DPRINT1("CtrlData->idProduct %x\n", CtrlData->idProduct);
-    DPRINT1("CtrlData->bcdDevice %x\n", CtrlData->bcdDevice);
-    DPRINT1("CtrlData->iManufacturer %x\n", CtrlData->iManufacturer);
-    DPRINT1("CtrlData->iProduct %x\n", CtrlData->iProduct);
-    DPRINT1("CtrlData->iSerialNumber %x\n", CtrlData->iSerialNumber);
-    DPRINT1("CtrlData->bNumConfigurations %x\n", CtrlData->bNumConfigurations);
-
-    /* Temporary: Remove */
-    if (CtrlData->bLength > 0)
-    {
-        /* We got valid data, try for strings */
-        UCHAR Manufacturer = CtrlData->iManufacturer;
-        UCHAR Product = CtrlData->iProduct;
-        UCHAR SerialNumber = CtrlData->iSerialNumber;
-
-        GetDeviceStringDescriptor(DeviceExtension, Manufacturer);
-        GetDeviceStringDescriptor(DeviceExtension, Product);
-        GetDeviceStringDescriptor(DeviceExtension, SerialNumber);
-    }
-
-    return TRUE;
-}
-
-BOOLEAN
-GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
-{
-    PEHCI_SETUP_FORMAT CtrlSetup = NULL;
-    PSTRING_DESCRIPTOR CtrlData = NULL;
-    PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL;
-    PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL;
-    PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL;
-    PQUEUE_HEAD QueueHead;
-    PEHCI_USBCMD_CONTENT UsbCmd;
-    PEHCI_USBSTS_CONTEXT UsbSts;
-    LONG Base;
-    LONG tmp;
-
-    Base = (ULONG) DeviceExtension->ResourceMemory;
-
-    /* Set up the QUEUE HEAD in memory */
-    QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr);
-
-    IntializeHeadQueueForStandardRequest(QueueHead,
-                                         &CtrlTD1,
-                                         &CtrlTD2,
-                                         &CtrlTD3,
-                                         &CtrlSetup,
-                                         (PVOID)&CtrlData,
-                                         sizeof(STRING_DESCRIPTOR) + 256);
-
-    /* FIXME: Use defines and handle other than Device Desciptors */
-    CtrlSetup->bmRequestType = 0x80;
-    CtrlSetup->bRequest = 0x06;
-    CtrlSetup->wValue = 0x0300 | Index;
-    CtrlSetup->wIndex = 0;
-    /* 256 pulled from thin air */
-    CtrlSetup->wLength = sizeof(STRING_DESCRIPTOR) + 256;
-
-    tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
-    UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
-    UsbCmd->Run = FALSE;
-    WRITE_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD), tmp);
-
-    /* Wait for the controller to halt */
-    for (;;)
+    if (CtrlSetup->bmRequestType._BM.Dir == BMREQUEST_DEVICE_TO_HOST)
     {
-        KeStallExecutionProcessor(10);
-        tmp = READ_REGISTER_ULONG((PULONG)(Base + EHCI_USBSTS));
-        UsbSts = (PEHCI_USBSTS_CONTEXT)&tmp;
-        DPRINT("Waiting for Halt, USBSTS: %x\n", READ_REGISTER_ULONG ((PULONG)(Base + EHCI_USBSTS)));
-        if (UsbSts->HCHalted)
+        if ((Buffer) && (BufferLength))
         {
-            break;
+            RtlCopyMemory(Buffer, CtrlData, BufferLength);
         }
+        else
+            DPRINT1("Unable to copy data to buffer\n");
     }
 
-    /* Set to TRUE on interrupt for async completion */
-    DeviceExtension->AsyncComplete = FALSE;
-    QueueHead->QETDPointer = (ULONG) MmGetPhysicalAddress((PVOID)(CtrlTD1)).LowPart;
-
-    tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
-    UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
-    UsbCmd->AsyncEnable = TRUE;
-
-    WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp);
-
-    tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
-    UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
-
-    /* Interrupt on Async completion */
-    UsbCmd->DoorBell = TRUE;
-    UsbCmd->Run = TRUE;
-    WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp);
-
-    for (;;)
-    {
-        KeStallExecutionProcessor(10);
-        DPRINT("Waiting for completion!\n");
-        if (DeviceExtension->AsyncComplete == TRUE)
-            break;
-    }
-
-    DPRINT1("String %S\n", &CtrlData->bString);
-
     return TRUE;
 }
-
index 1554069..0f35a31 100644 (file)
@@ -9,11 +9,6 @@
 
 /* DEFINES *******************************************************************/
 #include "usbehci.h"
-#define NDEBUG
-
-/* INCLUDES *******************************************************************/
-#include <debug.h>
-
 
 static NTSTATUS NTAPI
 IrpStub(PDEVICE_OBJECT DeviceObject, PIRP Irp)
index 13bfabb..56f03b5 100644 (file)
@@ -5,10 +5,12 @@
 #include <stdio.h>
 #define        NDEBUG
 #include <debug.h>
-#include "usbiffn.h"
+#include <hubbusif.h>
 #include <usbioctl.h>
 #include <usb.h>
 
+#define USB_POOL_TAG (ULONG)'UsbR'
+
 #define        DEVICEINTIALIZED                0x01
 #define        DEVICESTARTED                   0x02
 #define        DEVICEBUSY                      0x04
@@ -196,21 +198,46 @@ typedef struct _EHCI_SETUP_FORMAT
 
 typedef struct _STRING_DESCRIPTOR
 {
-  UCHAR bLength;               /* Size of this descriptor in bytes */
+  UCHAR bLength;            /* Size of this descriptor in bytes */
   UCHAR bDescriptorType;       /* STRING Descriptor Type */
-  UCHAR bString[0];            /* UNICODE encoded string */
+  UCHAR bString[0];         /* UNICODE encoded string */
 } STRING_DESCRIPTOR, *PSTRING_DESCRIPTOR;
 
+typedef struct _USB_ENDPOINT
+{
+    ULONG Flags;
+    LIST_ENTRY  UrbList;
+    struct _USB_INTERFACE *Interface;
+    USB_ENDPOINT_DESCRIPTOR EndPointDescriptor;
+} USB_ENDPOINT, *PUSB_ENDPOINT;
+
+typedef struct _USB_INTERFACE
+{
+    struct _USB_CONFIGURATION *Config;
+    USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+    USB_ENDPOINT *EndPoints[];
+} USB_INTERFACE, *PUSB_INTERFACE;
+
+typedef struct _USB_CONFIGURATION
+{
+    struct _USB_DEVICE *Device;
+    USB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
+    USB_INTERFACE *Interfaces[];
+} USB_CONFIGURATION, *PUSB_CONFIGURATION;
+
 typedef struct _USB_DEVICE
 {
     UCHAR Address;
     ULONG Port;
     PVOID ParentDevice;
     BOOLEAN IsHub;
+    USB_DEVICE_SPEED DeviceSpeed;
+    USB_DEVICE_TYPE DeviceType;
     USB_DEVICE_DESCRIPTOR DeviceDescriptor;
-    USB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
-    USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
-    USB_ENDPOINT_DESCRIPTOR EndPointDescriptor;
+    USB_CONFIGURATION *ActiveConfig;
+    USB_INTERFACE *ActiveInterface;
+    USB_CONFIGURATION **Configs;
+
 } USB_DEVICE, *PUSB_DEVICE;
 
 /* USBCMD register 32 bits */
@@ -380,11 +407,16 @@ typedef struct _PDO_DEVICE_EXTENSION
     PIRP CurrentIrp;
     HANDLE ThreadHandle;
     ULONG ChildDeviceCount;
-    BOOLEAN HaltUrbHandling;
+    BOOLEAN HaltQueue;
     PVOID CallbackContext;
-    PRH_INIT_CALLBACK CallbackRoutine;
+    RH_INIT_CALLBACK *CallbackRoutine;
+    USB_IDLE_CALLBACK IdleCallback;
+    PVOID IdleContext;
     ULONG NumberOfPorts;
     EHCIPORTS Ports[32];
+    KTIMER Timer;
+    KEVENT QueueDrainedEvent;
+    FAST_MUTEX ListLock;
 } PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
 
 typedef struct _WORKITEM_DATA
@@ -432,10 +464,7 @@ NTSTATUS NTAPI
 PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 
 BOOLEAN
-GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEVICE_DESCRIPTOR OutBuffer, BOOLEAN Hub);
-
-BOOLEAN
-GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index);
+ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, UCHAR Address, ULONG Port, PVOID Buffer, ULONG BufferLength);
 
 VOID
 QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp);
index 47fefb6..4dd98f4 100644 (file)
@@ -7,11 +7,57 @@
  *              Michael Martin
  */
 
-/* usbbusif.h and hubbusif.h need to be imported */
 #include "usbehci.h"
-#include "usbiffn.h"
-#define        NDEBUG
-#include <debug.h>
+#include <hubbusif.h>
+#include <usbbusif.h>
+
+PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub)
+{
+    PUSB_DEVICE UsbDevicePointer = NULL;
+    UsbDevicePointer = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_DEVICE), USB_POOL_TAG);
+
+    if (!UsbDevicePointer)
+    {
+        DPRINT1("Out of memory\n");
+        return NULL;
+    }
+
+    RtlZeroMemory(UsbDevicePointer, sizeof(USB_DEVICE));
+
+    if ((Hub) && (!Parent))
+    {
+        DPRINT1("This is the root hub\n");
+    }
+
+    UsbDevicePointer->Address = DeviceNumber;
+    UsbDevicePointer->Port = Port;
+    UsbDevicePointer->ParentDevice = Parent;
+
+    UsbDevicePointer->IsHub = Hub;
+
+    return UsbDevicePointer;
+}
+
+BOOLEAN
+IsHandleValid(PVOID BusContext,
+              PUSB_DEVICE_HANDLE DeviceHandle)
+{
+    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+    LONG i;
+
+    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) BusContext;
+
+    if (!DeviceHandle)
+        return FALSE;
+
+    for (i = 0; i < 128; i++)
+    {
+        if (PdoDeviceExtension->UsbDevices[i] == DeviceHandle)
+            return TRUE;
+    }
+
+    return FALSE;
+}
 
 VOID
 USB_BUSIFFN
@@ -36,15 +82,157 @@ CreateUsbDevice(PVOID BusContext,
                 PUSB_DEVICE_HANDLE HubDeviceHandle,
                 USHORT PortStatus, USHORT PortNumber)
 {
-    DPRINT1("CreateUsbDevice called\n");
+    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+    PUSB_DEVICE UsbDevice;
+    LONG i = 0;
+    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
+    DPRINT1("CreateUsbDevice: HubDeviceHandle %x, PortStatus %x, PortNumber %x\n", HubDeviceHandle, PortStatus, PortNumber);
+
+    UsbDevice = InternalCreateUsbDevice(PdoDeviceExtension->ChildDeviceCount, PortNumber, HubDeviceHandle, FALSE);
+
+    /* Add it to the list */
+    while (TRUE)
+    {
+        if (PdoDeviceExtension->UsbDevices[i] == NULL)
+        {
+            PdoDeviceExtension->UsbDevices[i] = (PUSB_DEVICE)UsbDevice;
+            PdoDeviceExtension->UsbDevices[i]->Address = i + 1;
+            PdoDeviceExtension->UsbDevices[i]->Port = PortNumber;
+            break; 
+        }
+        i++;
+    }
+
+    /* Return it */
+    *NewDevice = UsbDevice;
     return STATUS_SUCCESS;
 }
 
+/* Called when SCE reports a change */
+/* FIXME: Do something better for memory */
 NTSTATUS
 USB_BUSIFFN
 InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
 {
-    DPRINT1("InitializeUsbDevice called\n");
+    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc;
+    PUSB_INTERFACE_DESCRIPTOR InterfaceDesc;
+    PUSB_ENDPOINT_DESCRIPTOR EndpointDesc;
+    PUSB_DEVICE UsbDevice;
+    BOOLEAN ResultOk;
+    PVOID Buffer;
+    PUCHAR Ptr;
+    LONG i, j, k;
+
+    DPRINT1("InitializeUsbDevice called, device %x\n", DeviceHandle);
+    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
+    UsbDevice = (PUSB_DEVICE) DeviceHandle;
+
+    Buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, USB_POOL_TAG);
+
+    if (!Buffer)
+    {
+        DPRINT1("Out of memory\n");
+        return STATUS_NO_MEMORY;
+    }
+
+    Ptr = Buffer;
+    /* Set the device address */
+    CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+    CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+    CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_HOST_TO_DEVICE;
+    CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS;
+    CtrlSetup.wValue.W = UsbDevice->Address;
+    CtrlSetup.wIndex.W = 0;
+    CtrlSetup.wLength = 0;
+
+    ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, 0, 0, NULL, 0);
+
+    /* Get the Device Descriptor */
+    CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+    CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+    CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
+    CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
+    CtrlSetup.wValue.LowByte = 0;
+    CtrlSetup.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE;
+    CtrlSetup.wIndex.W = 0;
+    CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR);
+
+    ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, 
+                                     &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
+
+    DPRINT1("bLength %x\n", UsbDevice->DeviceDescriptor.bLength);
+    DPRINT1("bDescriptorType %x\n", UsbDevice->DeviceDescriptor.bDescriptorType);
+    DPRINT1("bNumDescriptors %x\n", UsbDevice->DeviceDescriptor.bNumConfigurations);
+
+    if (UsbDevice->DeviceDescriptor.bNumConfigurations == 0)
+        return STATUS_DEVICE_DATA_ERROR;
+
+    UsbDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
+                                               sizeof(PVOID) * UsbDevice->DeviceDescriptor.bNumConfigurations,
+                                               USB_POOL_TAG);
+
+    if (!UsbDevice->Configs)
+    {
+        DPRINT1("Out of memory\n");
+        return STATUS_NO_MEMORY;
+    }
+
+    for (i = 0; i < UsbDevice->DeviceDescriptor.bNumConfigurations; i++)
+    {
+        /* Get the Device Configuration Descriptor */
+        CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+        CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+        CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
+        CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
+        CtrlSetup.wValue.LowByte = 0;
+        CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE;
+        CtrlSetup.wIndex.W = 0;
+        CtrlSetup.wLength = PAGE_SIZE;
+
+        ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, Buffer, PAGE_SIZE);
+
+        ConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)Ptr;
+
+        ASSERT(ConfigDesc->wTotalLength <= PAGE_SIZE);
+
+        UsbDevice->Configs[i] = ExAllocatePoolWithTag(NonPagedPool,
+                                                      sizeof(USB_CONFIGURATION) + sizeof(PVOID) * ConfigDesc->bNumInterfaces,
+                                                      USB_POOL_TAG);
+        UsbDevice->Configs[i]->Device = UsbDevice;
+        RtlCopyMemory(&UsbDevice->Configs[0]->ConfigurationDescriptor,
+                      ConfigDesc, sizeof(USB_CONFIGURATION_DESCRIPTOR));
+        Ptr += ConfigDesc->bLength;
+
+        for (j = 0; j < ConfigDesc->bNumInterfaces; j++)
+        {
+            InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) Ptr;
+            UsbDevice->Configs[i]->Interfaces[j] = ExAllocatePoolWithTag(NonPagedPool,
+                                                                         sizeof(USB_INTERFACE) + sizeof(PVOID) * InterfaceDesc->bNumEndpoints,
+                                                                         USB_POOL_TAG);
+            RtlCopyMemory(&UsbDevice->Configs[i]->Interfaces[j]->InterfaceDescriptor,
+                          InterfaceDesc,
+                          sizeof(USB_INTERFACE_DESCRIPTOR));
+
+            Ptr += InterfaceDesc->bLength;
+
+            for (k = 0; k < InterfaceDesc->bNumEndpoints; k++)
+            {
+                EndpointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Ptr;
+                UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k] = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_ENDPOINT), USB_POOL_TAG);
+                RtlCopyMemory(&UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k]->EndPointDescriptor,
+                              EndpointDesc, sizeof(USB_ENDPOINT_DESCRIPTOR));
+            }
+
+        }
+    }
+
+    UsbDevice->ActiveConfig = UsbDevice->Configs[0];
+    UsbDevice->ActiveInterface = UsbDevice->Configs[0]->Interfaces[0];
+
     return STATUS_SUCCESS;
 }
 
@@ -54,10 +242,25 @@ GetUsbDescriptors(PVOID BusContext,
                   PUSB_DEVICE_HANDLE DeviceHandle,
                   PUCHAR DeviceDescriptorBuffer,
                   PULONG DeviceDescriptorBufferLength,
-                  PUCHAR ConfigurationBuffer,
+                  PUCHAR ConfigDescriptorBuffer,
                   PULONG ConfigDescriptorBufferLength)
 {
-    DPRINT1("GetUsbDescriptor called\n");
+    PUSB_DEVICE UsbDevice;
+    DPRINT1("GetUsbDescriptor %x, %d, %x, %d\n", DeviceDescriptorBuffer, DeviceDescriptorBufferLength, ConfigDescriptorBuffer, ConfigDescriptorBufferLength);
+
+    UsbDevice = (PUSB_DEVICE) DeviceHandle;
+
+    if ((DeviceDescriptorBuffer) && (DeviceDescriptorBufferLength))
+    {
+        RtlCopyMemory(DeviceDescriptorBuffer, &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
+        *DeviceDescriptorBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
+    }
+    if ((ConfigDescriptorBuffer) && (ConfigDescriptorBufferLength))
+    {
+        RtlCopyMemory(ConfigDescriptorBuffer, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
+        *ConfigDescriptorBufferLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
+    }
+
     return STATUS_SUCCESS;
 }
 
@@ -74,7 +277,7 @@ USB_BUSIFFN
 RestoreUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE OldDeviceHandle, PUSB_DEVICE_HANDLE NewDeviceHandle)
 {
     DPRINT1("RestoreUsbDevice called\n");
-    return STATUS_SUCCESS;
+    return STATUS_NOT_SUPPORTED;
 }
 
 NTSTATUS
@@ -82,7 +285,7 @@ USB_BUSIFFN
 GetPortHackFlags(PVOID BusContext, PULONG Flags)
 {
     DPRINT1("GetPortHackFlags called\n");
-    return STATUS_SUCCESS;
+    return STATUS_NOT_SUPPORTED;
 }
 
 NTSTATUS
@@ -93,7 +296,51 @@ QueryDeviceInformation(PVOID BusContext,
                        ULONG DeviceInformationBufferLength,
                        PULONG LengthReturned)
 {
-    DPRINT1("QueryDeviceInformation called\n");
+    PUSB_DEVICE_INFORMATION_0 DeviceInfo = DeviceInformationBuffer;
+    PUSB_DEVICE UsbDevice = (PUSB_DEVICE) DeviceHandle;
+    ULONG SizeNeeded;
+    LONG i;
+
+    DPRINT1("QueryDeviceInformation (%x, %x, %x, %d, %x\n", BusContext, DeviceHandle, DeviceInformationBuffer, DeviceInformationBufferLength, LengthReturned);
+
+    /* Search for a valid usb device in this BusContext */
+    if (!IsHandleValid(BusContext, DeviceHandle))
+    {
+        DPRINT1("Not a valid DeviceHandle\n");
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    SizeNeeded = FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints]);
+    *LengthReturned = SizeNeeded;
+
+    DeviceInfo->ActualLength = SizeNeeded;
+
+    if (DeviceInformationBufferLength < SizeNeeded)
+    {
+        DPRINT1("Buffer to small\n");
+        return STATUS_BUFFER_TOO_SMALL;
+    }
+
+    if (DeviceInfo->InformationLevel != 0)
+    {
+        DPRINT1("Invalid Param\n");
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    DeviceInfo->PortNumber = UsbDevice->Port;
+    DeviceInfo->HubAddress = 1;
+    DeviceInfo->DeviceAddress = UsbDevice->Address;
+    DeviceInfo->DeviceSpeed = UsbDevice->DeviceSpeed;
+    DeviceInfo->DeviceType = UsbDevice->DeviceType;
+    DeviceInfo->CurrentConfigurationValue = UsbDevice->ActiveConfig->ConfigurationDescriptor.bConfigurationValue;
+    DeviceInfo->NumberOfOpenPipes = UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints;
+
+    RtlCopyMemory(&DeviceInfo->DeviceDescriptor, &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
+
+    for (i = 0; i < UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints; i++)
+    {
+        RtlCopyMemory(&DeviceInfo->PipeList[i].EndpointDescriptor, &UsbDevice->ActiveInterface->EndPoints[i]->EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
+    }
     return STATUS_SUCCESS;
 }
 
@@ -104,7 +351,30 @@ GetControllerInformation(PVOID BusContext,
                          ULONG ControllerInformationBufferLength,
                          PULONG LengthReturned)
 {
+    PUSB_CONTROLLER_INFORMATION_0 ControllerInfo;
+
     DPRINT1("GetControllerInformation called\n");
+
+    ControllerInfo = ControllerInformationBuffer;
+
+    if (ControllerInformationBufferLength < sizeof(USB_CONTROLLER_INFORMATION_0))
+    {
+        DPRINT1("Buffer to small\n");
+        return STATUS_BUFFER_TOO_SMALL;
+    }
+
+    if (ControllerInfo->InformationLevel != 0)
+    {
+        DPRINT1("InformationLevel other than 0 not supported\n");
+        return STATUS_NOT_SUPPORTED;
+    }
+
+    ControllerInfo->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0);
+    ControllerInfo->SelectiveSuspendEnabled = FALSE;
+    ControllerInfo->IsHighSpeedController = TRUE;
+
+    *LengthReturned = ControllerInfo->ActualLength;
+
     return STATUS_SUCCESS;
 }
 
@@ -113,7 +383,7 @@ USB_BUSIFFN
 ControllerSelectiveSuspend(PVOID BusContext, BOOLEAN Enable)
 {
     DPRINT1("ControllerSelectiveSuspend called\n");
-    return STATUS_SUCCESS;
+    return STATUS_NOT_SUPPORTED;
 }
 
 NTSTATUS
@@ -129,7 +399,7 @@ GetExtendedHubInformation(PVOID BusContext,
     PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
     PFDO_DEVICE_EXTENSION FdoDeviceExntension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
     LONG i;
-
+    DPRINT1("GetExtendedHubInformation\n");
     /* Set the default return value */
     *LengthReturned = 0;
     /* Caller must have set InformationLevel to 0 */
@@ -162,6 +432,12 @@ GetRootHubSymbolicName(PVOID BusContext,
                        PULONG HubSymNameActualLength)
 {
     DPRINT1("GetRootHubSymbolicName called\n");
+
+    if (HubSymNameBufferLength < 16)
+        return STATUS_UNSUCCESSFUL;
+    RtlCopyMemory(HubSymNameBuffer, L"ROOT_HUB", HubSymNameBufferLength);
+    *HubSymNameActualLength = 16;
+
     return STATUS_SUCCESS;
 }
 
@@ -177,7 +453,11 @@ NTSTATUS
 USB_BUSIFFN
 Initialize20Hub(PVOID BusContext, PUSB_DEVICE_HANDLE HubDeviceHandle, ULONG TtCount)
 {
-    DPRINT1("Initialize20Hub called\n");
+    DPRINT1("Initialize20Hub called, HubDeviceHandle: %x\n", HubDeviceHandle);
+
+    /* FIXME: */
+    /* Create the Irp Queue for SCE */
+    /* Should queue be created for each device or each enpoint??? */
     return STATUS_SUCCESS;
 }
 
@@ -191,6 +471,17 @@ RootHubInitNotification(PVOID BusContext, PVOID CallbackContext, PRH_INIT_CALLBA
     PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
     PdoDeviceExtension->CallbackContext = CallbackContext;
     PdoDeviceExtension->CallbackRoutine = CallbackRoutine;
+    if (PdoDeviceExtension->CallbackRoutine)
+    {
+        DPRINT1("Called Callbackrountine\n");
+        PdoDeviceExtension->CallbackRoutine(PdoDeviceExtension->CallbackContext);
+        DPRINT1("Done Callbackrountine\n");
+    }
+    else
+    {
+        DPRINT1("PdoDeviceExtension->CallbackRoutine is NULL!\n");
+    }
+
     return STATUS_SUCCESS;
 }
 
@@ -211,12 +502,12 @@ SetDeviceHandleData(PVOID BusContext, PVOID DeviceHandle, PDEVICE_OBJECT UsbDevi
 
 /* USB_BUS_INTERFACE_USBDI_V2 Functions */
 
-NTSTATUS
+VOID
 USB_BUSIFFN
 GetUSBDIVersion(PVOID BusContext, PUSBD_VERSION_INFORMATION VersionInformation, PULONG HcdCapabilites)
 {
     DPRINT1("GetUSBDIVersion called\n");
-    return STATUS_SUCCESS;
+    return;
 }
 
 NTSTATUS
@@ -224,7 +515,7 @@ USB_BUSIFFN
 QueryBusTime(PVOID BusContext, PULONG CurrentFrame)
 {
     DPRINT1("QueryBusTime called\n");
-    return STATUS_SUCCESS;
+    return STATUS_NOT_SUPPORTED;
 }
 
 NTSTATUS
@@ -232,7 +523,7 @@ USB_BUSIFFN
 SubmitIsoOutUrb(PVOID BusContext, PURB Urb)
 {
     DPRINT1("SubmitIsoOutUrb called\n");
-    return STATUS_SUCCESS;
+    return STATUS_NOT_SUPPORTED;
 }
 
 NTSTATUS
@@ -244,7 +535,7 @@ QueryBusInformation(PVOID BusContext,
                     PULONG BusInformationActualLength)
 {
     DPRINT1("QueryBusInformation called\n");
-    return STATUS_SUCCESS;
+    return STATUS_NOT_SUPPORTED;
 }
 
 BOOLEAN
@@ -260,6 +551,5 @@ USB_BUSIFFN
 EnumLogEntry(PVOID BusContext, ULONG DriverTag, ULONG EnumTag, ULONG P1, ULONG P2)
 {
     DPRINT1("EnumLogEntry called\n");
-    return STATUS_SUCCESS;
+    return STATUS_NOT_SUPPORTED;
 }
-
index e9c2de4..eff48f0 100644 (file)
@@ -1,77 +1,12 @@
 #pragma once
 
-#define USB_BUSIFFN __stdcall
 #include <ntifs.h>
 #include <ntddk.h>
 #include <usb.h>
+#include <usbbusif.h>
 
-/* usbbusif.h and hubbusif.h need to be imported */
-typedef PVOID PUSB_DEVICE_HANDLE;
-
-typedef
-VOID
-USB_BUSIFFN
-RH_INIT_CALLBACK (PVOID CallBackContext);
-
-typedef RH_INIT_CALLBACK *PRH_INIT_CALLBACK;
-
-typedef struct _USB_EXTPORT_INFORMATION_0
-{
-    ULONG PhysicalPortNumber;
-    ULONG PortLabelNumber;
-    USHORT VidOverride;
-    USHORT PidOverride;
-    ULONG PortAttributes;
-} USB_EXTPORT_INFORMATION_0, *PUSB_EXTPORT_INFORMATION;
-
-typedef struct _USB_EXTHUB_INFORMATION_0
-{
-    ULONG InformationLevel;
-    ULONG NumberOfPorts;
-    USB_EXTPORT_INFORMATION_0 Port[255];
-} USB_EXTHUB_INFORMATION_0, *PUSB_EXTHUB_INFORMATION_0;
-
-typedef struct _USB_BUS_INTERFACE_USBDI_V2
-{
-    USHORT Size;
-    USHORT Version;
-    PVOID BusContext;
-    PINTERFACE_REFERENCE InterfaceReference;
-    PINTERFACE_DEREFERENCE InterfaceDereference;
-
-    PVOID GetUSBDIVersion;
-    PVOID QueryBusTime;
-    PVOID SubmitIsoOutUrb;
-    PVOID QueryBusInformation;
-    PVOID IsDeviceHighSpeed;
-    PVOID EnumLogEntry;
-} USB_BUS_INTERFACE_USBDI_V2, *PUSB_BUS_INTERFACE_USBDI_V2;
-
-typedef struct _USB_BUS_INTERFACE_HUB_V5
-{
-    USHORT Size;
-    USHORT Version;
-    PVOID BusContext;
-    PINTERFACE_REFERENCE InterfaceReference;
-    PINTERFACE_DEREFERENCE InterfaceDereference;
-
-    PVOID CreateUsbDevice;
-    PVOID InitializeUsbDevice;
-    PVOID GetUsbDescriptors;
-    PVOID RemoveUsbDevice;
-    PVOID RestoreUsbDevice;
-    PVOID GetPortHackFlags;
-    PVOID QueryDeviceInformation;
-    PVOID GetControllerInformation;
-    PVOID ControllerSelectiveSuspend;
-    PVOID GetExtendedHubInformation;
-    PVOID GetRootHubSymbolicName;
-    PVOID GetDeviceBusContext;
-    PVOID Initialize20Hub;
-    PVOID RootHubInitNotification;
-    PVOID FlushTransfers;
-    PVOID SetDeviceHandleData;
-} USB_BUS_INTERFACE_HUB_V5, *PUSB_BUS_INTERFACE_HUB_V5;
+PVOID
+InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub);
 
 VOID
 USB_BUSIFFN
@@ -98,7 +33,7 @@ GetUsbDescriptors(PVOID BusContext,
     PUSB_DEVICE_HANDLE DeviceHandle,
     PUCHAR DeviceDescriptorBuffer,
     PULONG DeviceDescriptorBufferLength,
-    PUCHAR ConfigurationBuffer,
+    PUCHAR ConfigDescriptorBuffer,
     PULONG ConfigDescriptorBufferLength);
 
 NTSTATUS
@@ -167,7 +102,7 @@ VOID
 USB_BUSIFFN
 SetDeviceHandleData(PVOID BusContext, PVOID DeviceHandle, PDEVICE_OBJECT UsbDevicePdo);
 
-NTSTATUS
+VOID
 USB_BUSIFFN
 GetUSBDIVersion(PVOID BusContext, PUSBD_VERSION_INFORMATION VersionInformation, PULONG HcdCapabilites);
 
index 698f879..c0d365b 100644 (file)
@@ -272,7 +272,7 @@ DrvSetPointerShape(
       VGADDI_ShowCursor(ppdev, prcl);
     }
 
-    return SPS_ACCEPT_EXCLUDE;
+    return SPS_ACCEPT_NOEXCLUDE;
 }
 
 static VOID FASTCALL
index 7cea4c0..9c8c482 100644 (file)
@@ -3,14 +3,15 @@
 <group xmlns:xi="http://www.w3.org/2001/XInclude">
 
        <xi:include href="hal_generic.rbuild" />
-       <xi:include href="hal_generic_up.rbuild" />
-       <xi:include href="hal_generic_mp.rbuild" />
        <xi:include href="hal_generic_pcat.rbuild" />
        <xi:include href="hal_generic_acpi.rbuild" />
-               
+
        <if property="ARCH" value="i386">
+               <xi:include href="hal_generic_up.rbuild" />
+               <xi:include href="hal_generic_mp.rbuild" />
+               <xi:include href="hal_mini.rbuild" />
                <xi:include href="hal.rbuild" />
-       <xi:include href="halacpi.rbuild" />
+               <xi:include href="halacpi.rbuild" />
                <xi:include href="halxbox.rbuild" />
                <if property="BUILD_MP" value="1">
                        <xi:include href="halmps.rbuild" />
index ca85188..8617b20 100644 (file)
@@ -848,9 +848,6 @@ HalpDriverEntry(IN PDRIVER_OBJECT DriverObject,
 
     /* Now add us */
     if (NT_SUCCESS(Status)) Status = HalpAddDevice(DriverObject, TargetDevice);
-    
-    /* Force re-enumeration??? */
-    IoInvalidateDeviceRelations(TargetDevice, 0);
 
     /* Return to kernel */
     return Status;
index 4309ac1..db54eb5 100644 (file)
@@ -145,33 +145,31 @@ HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress,
 
     /* Start at the current HAL heap base */
     BaseAddress = HalpHeapStart;
+    VirtualAddress = BaseAddress;
 
     /* Loop until we have all the pages required */
     while (UsedPages < PageCount)
     {
-        /* Begin a new loop cycle */
-        UsedPages = 0;
-        VirtualAddress = BaseAddress;
-
         /* If this overflows past the HAL heap, it means there's no space */
-        if (BaseAddress == NULL) return NULL;
+        if (VirtualAddress == NULL) return NULL;
+
+        /* Get the PTE for this address */
+        PointerPte = HalAddressToPte(VirtualAddress);
 
-        /* Loop until we have all the pages required in a single run */
-        while (UsedPages < PageCount)
+        /* Go to the next page */
+        VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
+
+        /* Check if the page is available */
+        if (PointerPte->Valid)
         {
-            /* Get the PTE for this address and check if it's available */
-            PointerPte = HalAddressToPte(VirtualAddress);
-            if (*(PULONG)PointerPte)
-            {
-                /* PTE has data, skip it and start with a new base address */
-                BaseAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
-                break;
-            }
-         
-            /* PTE is available, keep going on this run */
-            VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
-            UsedPages++;
+            /* PTE has data, skip it and start with a new base address */
+            BaseAddress = VirtualAddress;
+            UsedPages = 0;
+            continue;
         }
+
+        /* PTE is available, keep going on this run */
+        UsedPages++;
     }
 
     /* Take the base address of the page plus the actual offset in the address */
index 166bb93..8dd5f7b 100644 (file)
@@ -16,7 +16,6 @@
                                <file>sysbus.c</file>
                        </directory>
                        <file>beep.c</file>
-                       <file>bios.c</file>
                        <file>cmos.c</file>
                        <file>display.c</file>
                        <file>dma.c</file>
@@ -29,6 +28,7 @@
                        <file>timer.c</file>
                        <file>usage.c</file>
                        <if property="ARCH" value="i386">
+                               <file>bios.c</file>
                                <directory name="i386">
                                        <file>portio.c</file>
                                        <file>systimer.S</file>
                                </directory>
                        </if>
                        <if property="ARCH" value="amd64">
+                               <define name="_X86BIOS_" />
+                               <include base="x86emu">.</include>
                                <directory name="amd64">
                                        <file>x86bios.c</file>
+                                       <file>halinit.c</file>
+                                       <file>irq.S</file>
+                                       <file>misc.c</file>
+                                       <file>apic.c</file>
                                        <file>systimer.S</file>
+                                       <file>usage.c</file>
                                </directory>
                        </if>
                </directory>
                        <pch>hal.h</pch>
                </directory>
        </module>
-
-       <module name="mini_hal" type="objectlibrary" crt="static">
-               <include>include</include>
-               <include base="ntoskrnl">include</include>
-               <define name="_NTHALDLL_" />
-               <define name="_NTHAL_" />
-               <define name="_BLDR_" />
-               <define name="_MINIHAL_" />
-               <directory name="generic">
-                       <directory name="bus">
-                               <file>bushndlr.c</file>
-                               <file>isabus.c</file>
-                               <file>halbus.c</file>
-                               <file>pcibus.c</file>
-                               <file>pcidata.c</file>
-                               <file>sysbus.c</file>
-                       </directory>
-                       <file>beep.c</file>
-                       <file>bios.c</file>
-                       <file>cmos.c</file>
-                       <file>dma.c</file>
-                       <file>display.c</file>
-                       <file>drive.c</file>
-                       <file>misc.c</file>
-                       <file>profil.c</file>
-                       <file>reboot.c</file>
-                       <file>spinlock.c</file>
-                       <file>sysinfo.c</file>
-                       <file>timer.c</file>
-                       <file>usage.c</file>
-                       <if property="ARCH" value="i386">
-                               <directory name="i386">
-                                       <file>portio.c</file>
-                                       <file>systimer.S</file>
-                               </directory>
-                       </if>
-                               </directory>
-               <directory name="up">
-                       <file>halinit_up.c</file>
-                       <file>pic.c</file>
-                       <file>processor.c</file>
-               </directory>
-       </module>
 </group>
diff --git a/hal/halx86/hal_mini.rbuild b/hal/halx86/hal_mini.rbuild
new file mode 100644 (file)
index 0000000..a7baed4
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!DOCTYPE group SYSTEM "../../tools/rbuild/project.dtd">
+<group>
+       <module name="mini_hal" type="objectlibrary" crt="static">
+               <include>include</include>
+               <include base="ntoskrnl">include</include>
+               <define name="_NTHALDLL_" />
+               <define name="_NTHAL_" />
+               <define name="_BLDR_" />
+               <define name="_MINIHAL_" />
+               <directory name="generic">
+                       <directory name="bus">
+                               <file>bushndlr.c</file>
+                               <file>isabus.c</file>
+                               <file>halbus.c</file>
+                               <file>pcibus.c</file>
+                               <file>pcidata.c</file>
+                               <file>sysbus.c</file>
+                       </directory>
+                       <file>beep.c</file>
+                       <file>bios.c</file>
+                       <file>cmos.c</file>
+                       <file>dma.c</file>
+                       <file>display.c</file>
+                       <file>drive.c</file>
+                       <file>misc.c</file>
+                       <file>profil.c</file>
+                       <file>reboot.c</file>
+                       <file>spinlock.c</file>
+                       <file>sysinfo.c</file>
+                       <file>timer.c</file>
+                       <file>usage.c</file>
+                       <directory name="i386">
+                               <file>portio.c</file>
+                               <file>systimer.S</file>
+                       </directory>
+               </directory>
+               <directory name="up">
+                       <file>halinit_up.c</file>
+                       <file>pic.c</file>
+                       <file>processor.c</file>
+               </directory>
+       </module>
+</group>
index 0b60f76..ad96c0f 100644 (file)
        <define name="_X86BIOS_" />
        <library>hal_generic</library>
        <library>hal_generic_acpi</library>
-       <library>hal_generic_up</library>
        <library>ntoskrnl</library>
-       <!-- library>x86emu</library -->
+       <library>x86emu</library>
 
-       <directory name="mp">
+       <directory name="generic">
+               <file>spinlock.c</file>
+       </directory>
+
+       <directory name="up">
+               <file>processor.c</file>
+       </directory>
+
+       <!-- directory name="mp">
                <file>halinit_mp.c</file>
+               <file>processor_mp.c</file>
                <file>halmp.rc</file>
                <directory name="amd64">
-                       <!-- file>mps.S</file -->
+                       <file>mps.S</file>
                </directory>
-       </directory>
+       </directory -->
 </module>
 </group>
 
index e03f19e..cf97c5c 100644 (file)
@@ -1,8 +1,14 @@
 #pragma once
 
+#define _HUBBUSIF_
+
+#include "usbdi.h"
+
 #if (NTDDI_VERSION >= NTDDI_WINXP)
 
+#if !defined(_USBBUSIF_)
 typedef PVOID PUSB_DEVICE_HANDLE;
+#endif
 
 typedef struct _ROOTHUB_PDO_EXTENSION {
   ULONG Signature;
index 73aa6d6..5fd8438 100644 (file)
@@ -3283,13 +3283,14 @@ ExFreeToZone(
 #define ExIsResourceAcquired ExIsResourceAcquiredSharedLite
 #define ExReleaseResourceForThread ExReleaseResourceForThreadLite
 
+#ifdef _X86_
+
 typedef enum _INTERLOCKED_RESULT {
   ResultNegative = RESULT_NEGATIVE,
   ResultZero = RESULT_ZERO,
   ResultPositive = RESULT_POSITIVE
 } INTERLOCKED_RESULT;
 
-#ifdef _X86_
 NTKERNELAPI
 INTERLOCKED_RESULT
 FASTCALL
@@ -3308,8 +3309,8 @@ FASTCALL
 Exfi386InterlockedExchangeUlong(
   IN PULONG  Target,
   IN ULONG  Value);
-#endif
 
+#endif
 
 #if (NTDDI_VERSION >= NTDDI_WIN2K)
 NTKERNELAPI
index 0483738..3d1c1f3 100644 (file)
@@ -1,12 +1,16 @@
 #pragma once
 
+#define _USBBUSIF_
+
 #ifndef USB_BUSIFFN
 #define USB_BUSIFFN __stdcall
 #endif
 
 #if (NTDDI_VERSION >= NTDDI_WINXP)
 
+#if !defined(_USBBUSIF_)
 typedef PVOID PUSB_DEVICE_HANDLE;
+#endif
 
 typedef NTSTATUS
 (USB_BUSIFFN *PUSB_BUSIFFN_SUBMIT_ISO_OUT_URB) (
index 3cf12d5..f090af5 100644 (file)
@@ -317,6 +317,20 @@ typedef enum {
 }KSPROPERTY_BDA_SIGNAL_STATS;
 
 
+typedef struct tagBDA_TRANSPORT_INFO {
+    ULONG ulcbPhyiscalPacket;
+    ULONG ulcbPhyiscalFrame;
+    ULONG ulcbPhyiscalFrameAlignment;
+    REFERENCE_TIME AvgTimePerFrame;
+
+} BDA_TRANSPORT_INFO, *PBDA_TRANSPORT_INFO;
+
+typedef struct tagKS_DATARANGE_BDA_TRANSPORT
+{
+   KSDATARANGE                  DataRange;
+   BDA_TRANSPORT_INFO           BdaTransportInfo;
+} KS_DATARANGE_BDA_TRANSPORT, *PKS_DATARANGE_BDA_TRANSPORT;
+
 /* ------------------------------------------------------------
   BDA Stream Format GUIDs
 */
index 42f30ed..07146c4 100644 (file)
@@ -65,6 +65,7 @@ typedef PVOID HANDLE, HKEY, *PHKEY;
 typedef INT NTSTATUS, POOL_TYPE;
 typedef LONG HRESULT;
 typedef ULONG_PTR SIZE_T, *PSIZE_T;
+typedef WORD LANGID;
 
 #define MAXUSHORT USHRT_MAX
 
@@ -232,6 +233,11 @@ typedef const UNICODE_STRING *PCUNICODE_STRING;
 #define RtlCopyMemory(Destination, Source, Length)    memcpy(Destination, Source, Length)
 #define RtlMoveMemory(Destination, Source, Length)    memmove(Destination, Source, Length)
 
+#define MAKELANGID(p,s)         ((((WORD)(s))<<10)|(WORD)(p))
+#define PRIMARYLANGID(l)        ((WORD)(l)&0x3ff)
+#define SUBLANGID(l)            ((WORD)(l)>>10)
+#define SUBLANG_NEUTRAL         0x00
+
 /* Prevent inclusion of some other headers */
 #define __INTERNAL_DEBUG
 #define RTL_H
index bf2c127..c07679a 100644 (file)
 
 #ifdef USE_HOST_WCSFUNCS
     /* Function prototypes */
-    SIZE_T utf16_wcslen(PCWSTR str);
-    PWSTR utf16_wcschr(PWSTR str, WCHAR c);
-    INT utf16_wcsncmp(PCWSTR string1, PCWSTR string2, size_t count);
+
 #else
-    /* Define the utf16_ functions to the CRT functions */
-    #define utf16_wcslen  wcslen
-    #define utf16_wcschr  wcschr
-    #define utf16_wcsncmp wcsncmp
+    /* Map str*W functions to wcs* function */
+
+    #define isspaceW iswspace
+    #define strchrW  wcschr
+    #define strcmpiW _wcsicmp
+    #define strcpyW  wcscpy
+    #define strlenW  wcslen
+    #define strncmpW wcsncmp
+    #define strtolW  wcstol
+    #define strtoulW wcstoul
+
 #endif
 
 #endif
index b572420..8e4d421 100644 (file)
@@ -58,12 +58,14 @@ Author:
 //
 #define RPL_MASK                0x0003
 #define MODE_MASK               0x0001
-#define KGDT_64_R0_CODE         0x0010
-#define KGDT_64_R0_SS           0x0018
-#define KGDT_64_DATA            0x0028 // 2b
-#define KGDT_64_R3_CODE         0x0030 // 33
-#define KGDT_TSS                0x0040
-#define KGDT_32_R3_TEB          0x0050 // 53
+#define KGDT64_NULL             0x0000
+#define KGDT64_R0_CODE          0x0010
+#define KGDT64_R0_DATA          0x0018
+#define KGDT64_R3_CMCODE        0x0020
+#define KGDT64_R3_DATA          0x0028
+#define KGDT64_R3_CODE          0x0030
+#define KGDT64_SYS_TSS          0x0040
+#define KGDT64_R3_CMTEB         0x0050
 
 
 //
index cd97a70..8312e16 100644 (file)
@@ -561,8 +561,9 @@ GpStatus WINGDIPAPI GdipSetPathGradientFocusScales(GpPathGradient*,REAL,REAL);
 GpStatus WINGDIPAPI GdipSetPathGradientGammaCorrection(GpPathGradient*,BOOL);
 GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient*,REAL,REAL);
 GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient*,
-    ARGB*,INT*);
+    GDIPCONST ARGB*,INT*);
 GpStatus WINGDIPAPI GdipSetPathGradientWrapMode(GpPathGradient*,GpWrapMode);
+GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorCount(GpPathGradient*,INT*);
 
 /* PathIterator */
 GpStatus WINGDIPAPI GdipCreatePathIter(GpPathIterator**,GpPath*);
index f728bfb..2290d7c 100644 (file)
@@ -744,6 +744,99 @@ typedef enum
     KSPROPERTY_STREAM_PIPE_ID
 } KSPROPERTY_STREAM;
 
+#define DEFINE_KSPROPERTY_ITEM_STREAM_ALLOCATOR(GetHandler, SetHandler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_STREAM_ALLOCATOR,\
+        (GetHandler),\
+        sizeof(KSPROPERTY),\
+        sizeof(HANDLE),\
+        (SetHandler),\
+        NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_STREAM_QUALITY(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_STREAM_QUALITY,\
+        (Handler),\
+        sizeof(KSPROPERTY),\
+        sizeof(KSQUALITY_MANAGER),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_STREAM_DEGRADATION(GetHandler, SetHandler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_STREAM_DEGRADATION,\
+        (GetHandler),\
+        sizeof(KSPROPERTY),\
+        0,\
+        (SetHandler),\
+        NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_STREAM_MASTERCLOCK(GetHandler, SetHandler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_STREAM_MASTERCLOCK,\
+        (GetHandler),\
+        sizeof(KSPROPERTY),\
+        sizeof(HANDLE),\
+        (SetHandler),\
+        NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_STREAM_TIMEFORMAT(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_STREAM_TIMEFORMAT,\
+        (Handler),\
+        sizeof(KSPROPERTY),\
+        sizeof(GUID),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_STREAM_PRESENTATIONTIME(GetHandler, SetHandler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_STREAM_PRESENTATIONTIME,\
+        (GetHandler),\
+        sizeof(KSPROPERTY),\
+        sizeof(KSTIME),\
+        (SetHandler),\
+        NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_STREAM_PRESENTATIONEXTENT(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_STREAM_PRESENTATIONEXTENT,\
+        (Handler),\
+        sizeof(KSPROPERTY),\
+        sizeof(LONGLONG),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_STREAM_FRAMETIME(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_STREAM_FRAMETIME,\
+        (Handler),\
+        sizeof(KSPROPERTY),\
+        sizeof(KSFRAMETIME),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_STREAM_RATECAPABILITY(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_STREAM_RATECAPABILITY,\
+        (Handler),\
+        sizeof(KSRATE_CAPABILITY),\
+        sizeof(KSRATE),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_STREAM_RATE(GetHandler, SetHandler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_STREAM_RATE,\
+        (GetHandler),\
+        sizeof(KSPROPERTY),\
+        sizeof(KSRATE),\
+        (SetHandler),\
+        NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_STREAM_PIPE_ID(GetHandler, SetHandler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_STREAM_PIPE_ID,\
+        (GetHandler),\
+        sizeof(KSPROPERTY),\
+        sizeof(HANDLE),\
+        (SetHandler),\
+        NULL, 0, NULL, NULL, 0)
 
 /* ===============================================================
     StreamAllocator
@@ -1926,6 +2019,76 @@ typedef struct
 } KSCLOCK_FUNCTIONTABLE, *PKSCLOCK_FUNCTIONTABLE;
 
 
+#define DEFINE_KSPROPERTY_ITEM_CLOCK_TIME(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_CLOCK_TIME,\
+        (Handler),\
+        sizeof(KSPROPERTY),\
+        sizeof(LONGLONG),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_CLOCK_PHYSICALTIME(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_CLOCK_PHYSICALTIME,\
+        (Handler),\
+        sizeof(KSPROPERTY),\
+        sizeof(LONGLONG),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDTIME(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_CLOCK_CORRELATEDTIME,\
+        (Handler),\
+        sizeof(KSPROPERTY),\
+        sizeof(KSCORRELATED_TIME),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDPHYSICALTIME(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME,\
+        (Handler),\
+        sizeof(KSPROPERTY),\
+        sizeof(KSCORRELATED_TIME),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_CLOCK_RESOLUTION(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_CLOCK_RESOLUTION,\
+        (Handler),\
+        sizeof(KSPROPERTY),\
+        sizeof(KSRESOLUTION),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_CLOCK_STATE(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_CLOCK_STATE,\
+        (Handler),\
+        sizeof(KSPROPERTY),\
+        sizeof(KSSTATE),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_ITEM_CLOCK_FUNCTIONTABLE(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_CLOCK_FUNCTIONTABLE,\
+        (Handler),\
+        sizeof(KSPROPERTY),\
+        sizeof(KSCLOCK_FUNCTIONTABLE),\
+        NULL, NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_CLOCKSET(ClockSet,\
+    PropTime, PropPhysicalTime,\
+    PropCorrelatedTime, PropCorrelatedPhysicalTime,\
+    PropResolution, PropState, PropFunctionTable)\
+DEFINE_KSPROPERTY_TABLE(ClockSet) {\
+    DEFINE_KSPROPERTY_ITEM_CLOCK_TIME(PropTime),\
+    DEFINE_KSPROPERTY_ITEM_CLOCK_PHYSICALTIME(PropPhysicalTime),\
+    DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDTIME(PropCorrelatedTime),\
+    DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDPHYSICALTIME(PropCorrelatedPhysicalTime),\
+    DEFINE_KSPROPERTY_ITEM_CLOCK_RESOLUTION(PropResolution),\
+    DEFINE_KSPROPERTY_ITEM_CLOCK_STATE(PropState),\
+    DEFINE_KSPROPERTY_ITEM_CLOCK_FUNCTIONTABLE(PropFunctionTable)\
+}
+
 /* ===============================================================
     Objects ??? SORT ME!
 */
index da90916..a1b1c0c 100644 (file)
@@ -14,6 +14,8 @@
     KS CATEGORIES
 */
 
+typedef LONGLONG REFERENCE_TIME;
+
 #define EXTRACT_WAVEFORMATEX_ID(Guid)\
     (USHORT)((Guid)->Data1)
 
index fdc3650..18107cd 100644 (file)
@@ -565,6 +565,9 @@ typedef struct _PROCESSOR_NUMBER {
   UCHAR Reserved;
 } PROCESSOR_NUMBER, *PPROCESSOR_NUMBER;
 
+struct _CONTEXT;
+struct _EXCEPTION_RECORD;
+
 typedef EXCEPTION_DISPOSITION
 (NTAPI *PEXCEPTION_ROUTINE)(
   IN struct _EXCEPTION_RECORD *ExceptionRecord,
index 4de56cc..b83d364 100644 (file)
 #ifndef _NTSECPKG_H
 #define _NTSECPKG_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* Flags for the MachineState field in SECPKG_PARAMETERS */
 #define SECPKG_STATE_ENCRYPTION_PERMITTED               0x01
 #define SECPKG_STATE_STRONG_ENCRYPTION_PERMITTED        0x02
@@ -30,6 +34,9 @@
 #define SECPKG_INTERFACE_VERSION                     0x10000
 #define SECPKG_INTERFACE_VERSION_2                   0x20000
 #define SECPKG_INTERFACE_VERSION_3                   0x40000
+#define SECPKG_INTERFACE_VERSION_4                   0x80000
+#define SECPKG_INTERFACE_VERSION_5                  0x100000
+#define SECPKG_INTERFACE_VERSION_6                  0x200000
 
 /* enum definitions for Secure Service Provider/Authentication Packages */
 typedef enum _LSA_TOKEN_INFORMATION_TYPE {
@@ -140,6 +147,11 @@ typedef struct _SECPKG_EXTENDED_INFORMATION {
     } Info;
 } SECPKG_EXTENDED_INFORMATION, *PSECPKG_EXTENDED_INFORMATION;
 
+typedef struct  _SECPKG_TARGETINFO {
+    PSID DomainSid;
+    PCWSTR ComputerName;
+} SECPKG_TARGETINFO, *PSECPKG_TARGETINFO;
+
 /* callbacks implemented by SSP/AP dlls and called by the LSA */
 typedef VOID (NTAPI *PLSA_CALLBACK_FUNCTION)(ULONG_PTR, ULONG_PTR, PSecBuffer,
  PSecBuffer);
@@ -341,6 +353,18 @@ typedef NTSTATUS (NTAPI SpSetContextAttributesFn)(LSA_SEC_HANDLE, ULONG, PVOID,
  ULONG);
 typedef NTSTATUS (NTAPI SpSetCredentialsAttributesFn)(LSA_SEC_HANDLE, ULONG,
  PVOID, ULONG);
+typedef NTSTATUS (NTAPI SpChangeAccountPasswordFn)(PUNICODE_STRING,
+ PUNICODE_STRING, PUNICODE_STRING, PUNICODE_STRING, BOOLEAN, PSecBufferDesc);
+typedef NTSTATUS (NTAPI SpQueryMetaDataFn)(LSA_SEC_HANDLE, PUNICODE_STRING,
+ ULONG, PULONG, PUCHAR *, PLSA_SEC_HANDLE);
+typedef NTSTATUS (NTAPI SpExchangeMetaDataFn)(LSA_SEC_HANDLE, PUNICODE_STRING,
+ ULONG, ULONG, PUCHAR, PLSA_SEC_HANDLE);
+typedef NTSTATUS (NTAPI SpGetCredUIContextFn)(LSA_SEC_HANDLE, GUID *, PULONG,
+ PUCHAR *);
+typedef NTSTATUS (NTAPI SpUpdateCredentialsFn)(LSA_SEC_HANDLE, GUID *, ULONG,
+ PUCHAR);
+typedef NTSTATUS (NTAPI SpValidateTargetInfoFn)(PLSA_CLIENT_REQUEST, PVOID,
+ PVOID, ULONG, PSECPKG_TARGETINFO);
 
 /* User-mode functions implemented by SSP/AP obtainable by a dispatch table */
 typedef NTSTATUS (NTAPI SpInstanceInitFn)(ULONG, PSECPKG_DLL_FUNCTIONS,
@@ -402,6 +426,15 @@ typedef struct SECPKG_FUNCTION_TABLE {
     /* Packages with version SECPKG_INTERFACE_VERSION_2 end here */
     SpSetCredentialsAttributesFn *SetCredentialsAttributes;
     /* Packages with version SECPKG_INTERFACE_VERSION_3 end here */
+    SpChangeAccountPasswordFn *ChangeAccountPassword;
+    /* Packages with version SECPKG_INTERFACE_VERSION_4 end here */
+    SpQueryMetaDataFn *QueryMetaData;
+    SpExchangeMetaDataFn *ExchangeMetaData;
+    SpGetCredUIContextFn *GetCredUIContext;
+    SpUpdateCredentialsFn *UpdateCredentials;
+    /* Packages with version SECPKG_INTERFACE_VERSION_5 end here */
+    SpValidateTargetInfoFn *ValidateTargetInfo;
+    /* Packages with version SECPKG_INTERFACE_VERSION_6 end here */
 } SECPKG_FUNCTION_TABLE,
  *PSECPKG_FUNCTION_TABLE;
 
@@ -432,4 +465,7 @@ typedef NTSTATUS (NTAPI *SpLsaModeInitializeFn)(ULONG, PULONG,
 typedef NTSTATUS (WINAPI *SpUserModeInitializeFn)(ULONG, PULONG,
  PSECPKG_USER_FUNCTION_TABLE *, PULONG);
 
+#ifdef __cplusplus
+}
+#endif
 #endif /* _NTSECPKG_H */
index 57da913..e9295de 100644 (file)
 #define THIS   void
 
 #define interface struct
-#define DECLARE_INTERFACE(iface)        interface iface
-#define DECLARE_INTERFACE_(iface,ibase) interface iface : public ibase
-#define DECLARE_INTERFACE_IID(iface, iid)             interface DECLSPEC_UUID(iid) iface
-#define DECLARE_INTERFACE_IID_(iface, baseiface, iid) interface DECLSPEC_UUID(iid) iface : public baseiface
+#define DECLARE_INTERFACE(iface)        interface DECLSPEC_NOVTABLE iface
+#define DECLARE_INTERFACE_(iface,ibase) interface DECLSPEC_NOVTABLE iface : public ibase
+#define DECLARE_INTERFACE_IID_(iface, ibase, iid) interface DECLSPEC_UUID(iid) DECLSPEC_NOVTABLE iface : public ibase
 
 #define BEGIN_INTERFACE
 #define END_INTERFACE
          struct iface##Vtbl
 #endif
 #define DECLARE_INTERFACE_(iface,ibase) DECLARE_INTERFACE(iface)
+#define DECLARE_INTERFACE_IID_(iface, ibase, iid) DECLARE_INTERFACE_(iface, ibase)
 
 #define BEGIN_INTERFACE
 #define END_INTERFACE
@@ -431,7 +431,7 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags,DWORD dwTimeout,ULONG cHan
  *     GUID API
  */
 HRESULT WINAPI StringFromCLSID(REFCLSID id, LPOLESTR*);
-HRESULT WINAPI CLSIDFromString(LPOLESTR, CLSID *);
+HRESULT WINAPI CLSIDFromString(LPCOLESTR, LPCLSID);
 HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid);
 HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID);
 
index 02256eb..ebf38da 100644 (file)
@@ -47,6 +47,7 @@
        <file>richole.idl</file>
        <file>sensevts.idl</file>
        <file>servprov.idl</file>
+       <file>shdeprecated.idl</file>
        <file>shldisp.idl</file>
        <file>shobjidl.idl</file>
        <file>shtypes.idl</file>
@@ -68,6 +69,8 @@
        <file>xmldso.idl</file>
        <file>xmldom.idl</file>
        <file>xmllite.idl</file>
+       <file>wia_lh.idl</file>
+       <file>wia_xp.idl</file>
 </module>
 <module name="stdole2" type="embeddedtypelib">
        <file>stdole2.idl</file>
diff --git a/include/psdk/shdeprecated.idl b/include/psdk/shdeprecated.idl
new file mode 100644 (file)
index 0000000..304b087
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Deprecated shell interfaces
+ *
+ * Copyright (C) 2010 Nikolay Sivov for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+import "objidl.idl";
+
+[
+    object,
+    local,
+    uuid(5836fb00-8187-11cf-a12b-00aa004ae837)
+]
+interface IShellService : IUnknown
+{
+    HRESULT SetOwner( [in] IUnknown *pUnk );
+}
index 29e70b7..223bcdd 100644 (file)
@@ -1028,24 +1028,6 @@ typedef struct _DLLVERSIONINFO2 {
 HRESULT WINAPI DllInstall(BOOL,LPCWSTR) DECLSPEC_HIDDEN;
 
 
-#if (_WIN32_IE >= 0x0600)
-#define SHGVSPB_PERUSER        0x00000001
-#define SHGVSPB_ALLUSERS       0x00000002
-#define SHGVSPB_PERFOLDER      0x00000004
-#define SHGVSPB_ALLFOLDERS     0x00000008
-#define SHGVSPB_INHERIT        0x00000010
-#define SHGVSPB_ROAM           0x00000020
-#define SHGVSPB_NOAUTODEFAULTS 0x80000000
-
-#define SHGVSPB_FOLDER           (SHGVSPB_PERUSER | SHGVSPB_PERFOLDER)
-#define SHGVSPB_FOLDERNODEFAULTS (SHGVSPB_PERUSER | SHGVSPB_PERFOLDER | SHGVSPB_NOAUTODEFAULTS)
-#define SHGVSPB_USERDEFAULTS     (SHGVSPB_PERUSER | SHGVSPB_ALLFOLDERS)
-#define SHGVSPB_GLOBALDEAFAULTS  (SHGVSPB_ALLUSERS | SHGVSPB_ALLFOLDERS)
-
-HRESULT WINAPI SHGetViewStatePropertyBag(LPCITEMIDLIST pidl, LPWSTR bag_name, DWORD flags, REFIID riid, void **ppv);
-#endif  /* (_WIN32_IE >= 0x0600) */
-
-
 /* IsOS definitions */
 
 #define OS_WIN32SORGREATER        0x00
@@ -1103,6 +1085,15 @@ BOOL WINAPI IsOS(DWORD);
 #define FDTF_RTLDATE            0x00000200
 #define FDTF_NOAUTOREADINGORDER 0x00000400
 
+
+typedef struct
+{
+    const IID *piid;
+    int        dwOffset;
+} QITAB, *LPQITAB;
+
+HRESULT WINAPI QISearch(void* base, const QITAB *pqit, REFIID riid, void **ppv);
+
 #include <poppack.h> 
 
 #ifdef __cplusplus
index 56650f5..204492d 100644 (file)
@@ -31,6 +31,147 @@ extern "C" {
 
 DEFINE_GUID(CLSID_Sti, 0xB323F8E0L, 0x2E68, 0x11D0, 0x90, 0xEA, 0x00, 0xAA, 0x00, 0x60, 0xF8, 0x6C);
 
+DEFINE_GUID(IID_IStillImageW, 0x641BD880, 0x2DC8, 0x11D0, 0x90, 0xEA, 0x00, 0xAA, 0x00, 0x60, 0xF8, 0x6C);
+
+DEFINE_GUID(IID_IStillImageA, 0xA7B1F740, 0x1D7F, 0x11D1, 0xAC, 0xA9, 0x00, 0xA0, 0x24, 0x38, 0xAD, 0x48);
+
+#define STI_VERSION_REAL         0x00000002
+#define STI_VERSION_FLAG_UNICODE 0x01000000
+
+#ifndef WINE_NO_UNICODE_MACROS
+# ifdef UNICODE
+#  define STI_VERSION (STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE)
+# else
+#  define STI_VERSION (STI_VERSION_REAL)
+# endif
+#endif
+
+typedef struct IStillImageA *PSTIA;
+typedef struct IStillImageW *PSTIW;
+DECL_WINELIB_TYPE_AW(PSTI)
+typedef struct IStillImageA *LPSTILLIMAGEA;
+typedef struct IStillImageW *LPSTILLIMAGEW;
+DECL_WINELIB_TYPE_AW(LPSTILLIMAGE)
+typedef struct IStiDeviceA *PSTIDEVICEA;
+typedef struct IStiDeviceW *PSTIDEVICEW;
+DECL_WINELIB_TYPE_AW(PSTIDEVICE)
+
+HRESULT WINAPI StiCreateInstanceA(HINSTANCE hinst, DWORD dwVer, PSTIA *ppSti, LPUNKNOWN pUnkOuter);
+HRESULT WINAPI StiCreateInstanceW(HINSTANCE hinst, DWORD dwVer, PSTIW *ppSti, LPUNKNOWN pUnkOuter);
+#define        StiCreateInstance WINELIB_NAME_AW(StiCreateInstance)
+
+typedef DWORD STI_DEVICE_TYPE;
+typedef enum _STI_DEVICE_MJ_TYPE
+{
+    StiDeviceTypeDefault           = 0,
+    StiDeviceTypeScanner           = 1,
+    StiDeviceTypeDigitalCamera     = 2,
+    StiDeviceTypeStreamingVideo    = 3
+} STI_DEVICE_MJ_TYPE;
+
+#define GET_STIDEVICE_TYPE(dwDevType) HIWORD(dwDevType)
+#define GET_STIDEVICE_SUBTYPE(dwDevType) LOWORD(dwDevType)
+
+typedef struct _STI_DEV_CAPS {
+    DWORD dwGeneric;
+} STI_DEV_CAPS, *PSTI_DEV_CAPS;
+
+#define STI_MAX_INTERNAL_NAME_LENGTH 128
+
+typedef struct _STI_DEVICE_INFORMATIONW {
+    DWORD dwSize;
+    STI_DEVICE_TYPE DeviceType;
+    WCHAR szDeviceInternalName[STI_MAX_INTERNAL_NAME_LENGTH];
+    STI_DEV_CAPS DeviceCapabilities;
+    DWORD dwHardwareConfiguration;
+    LPWSTR pszVendorDescription;
+    LPWSTR pszDeviceDescription;
+    LPWSTR pszPortName;
+    LPWSTR pszPropProvider;
+    LPWSTR pszLocalName;
+} STI_DEVICE_INFORMATIONW, *PSTI_DEVICE_INFORMATIONW;
+
+typedef STI_DEVICE_INFORMATIONW STI_DEVICE_INFORMATION;
+typedef PSTI_DEVICE_INFORMATIONW PSTI_DEVICE_INFORMATION;
+
+#define MAX_NOTIFICATION_DATA 64
+
+typedef struct _STINOTIFY {
+    DWORD dwSize;
+    GUID guidNotificationCode;
+    BYTE abNotificationData[MAX_NOTIFICATION_DATA];
+} STINOTIFY,*LPSTINOTIFY;
+
+#define INTERFACE IStillImageW
+DECLARE_INTERFACE_(IStillImageW, IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IStillImageW methods ***/
+    STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+    STDMETHOD(GetDeviceList)(THIS_ DWORD dwType, DWORD dwFlags, DWORD *pdwItemsReturned, LPVOID *ppBuffer) PURE;
+    STDMETHOD(GetDeviceInfo)(THIS_ LPWSTR pwszDeviceName, LPVOID *ppBuffer) PURE;
+    STDMETHOD(CreateDevice)(THIS_ LPWSTR pwszDeviceName, DWORD dwMode, PSTIDEVICEW *pDevice, LPUNKNOWN pUnkOuter) PURE;
+    STDMETHOD(GetDeviceValue)(THIS_ LPWSTR pwszDeviceName, LPWSTR pValueName, LPDWORD pType, LPBYTE pData, LPDWORD cbData) PURE;
+    STDMETHOD(SetDeviceValue)(THIS_ LPWSTR pwszDeviceName, LPWSTR pValueName, DWORD type, LPBYTE pData, DWORD cbData) PURE;
+    STDMETHOD(GetSTILaunchInformation)(THIS_ LPWSTR pwszDeviceName, DWORD *pdwEventCode, LPWSTR pwszEventName) PURE;
+    STDMETHOD(RegisterLaunchApplication)(THIS_ LPWSTR pwszAppName, LPWSTR pwszCommandLine) PURE;
+    STDMETHOD(UnregisterLaunchApplication)(THIS_ LPWSTR pwszAppName) PURE;
+    STDMETHOD(EnableHwNotifications)(THIS_ LPCWSTR pwszDeviceName, BOOL bNewState) PURE;
+    STDMETHOD(GetHwNotificationState)(THIS_ LPCWSTR pwszDeviceName, BOOL *pbCurrentState) PURE;
+    STDMETHOD(RefreshDeviceBus)(THIS_ LPCWSTR pwszDeviceName) PURE;
+    STDMETHOD(LaunchApplicationForDevice)(THIS_ LPWSTR pwszDeviceName, LPWSTR pwszAppName, LPSTINOTIFY pStiNotify);
+    STDMETHOD(SetupDeviceParameters)(THIS_ PSTI_DEVICE_INFORMATIONW pDevInfo);
+    STDMETHOD(WriteToErrorLog)(THIS_ DWORD dwMessageType, LPCWSTR pszMessage) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IStillImage_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IStillImage_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IStillImage_Release(p)            (p)->lpVtbl->Release(p)
+/*** IStillImage methods ***/
+#define IStillImage_Initialize(p,a,b)                   (p)->lpVtbl->Initialize(p,a,b)
+#define IStillImage_GetDeviceList(p,a,b,c,d)            (p)->lpVtbl->GetDeviceList(p,a,b,c,d)
+#define IStillImage_GetDeviceInfo(p,a,b)                (p)->lpVtbl->GetDeviceInfo(p,a,b)
+#define IStillImage_CreateDevice(p,a,b,c,d)             (p)->lpVtbl->CreateDevice(p,a,b,c,d)
+#define IStillImage_GetDeviceValue(p,a,b,c,d,e)         (p)->lpVtbl->GetDeviceValue(p,a,b,c,d,e)
+#define IStillImage_SetDeviceValue(p,a,b,c,d,e)         (p)->lpVtbl->SetDeviceValue(p,a,b,c,d,e)
+#define IStillImage_GetSTILaunchInformation(p,a,b,c)    (p)->lpVtbl->GetSTILaunchInformation(p,a,b,c)
+#define IStillImage_RegisterLaunchApplication(p,a,b)    (p)->lpVtbl->RegisterLaunchApplication(p,a,b)
+#define IStillImage_UnregisterLaunchApplication(p,a)    (p)->lpVtbl->UnregisterLaunchApplication(p,a)
+#define IStillImage_EnableHwNotifications(p,a,b)        (p)->lpVtbl->EnableHwNotifications(p,a,b)
+#define IStillImage_GetHwNotificationState(p,a,b)       (p)->lpVtbl->GetHwNotificationState(p,a,b)
+#define IStillImage_RefreshDeviceBus(p,a)               (p)->lpVtbl->RefreshDeviceBus(p,a)
+#define IStillImage_LaunchApplicationForDevice(p,a,b,c) (p)->lpVtbl->LaunchApplicationForDevice(p,a,b,c)
+#define IStillImage_SetupDeviceParameters(p,a)          (p)->lpVtbl->SetupDeviceParameters(p,a)
+#define IStillImage_WriteToErrorLog(p,a,b)              (p)->lpVtbl->WriteToErrorLog(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IStillImage_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IStillImage_AddRef(p)             (p)->AddRef()
+#define IStillImage_Release(p)            (p)->Release()
+/*** IStillImage methods ***/
+#define IStillImage_Initialize(p,a,b)                   (p)->Initialize(a,b)
+#define IStillImage_GetDeviceList(p,a,b,c,d)            (p)->GetDeviceList(a,b,c,d)
+#define IStillImage_GetDeviceInfo(p,a,b)                (p)->GetDeviceInfo(a,b)
+#define IStillImage_CreateDevice(p,a,b,c,d)             (p)->CreateDevice(a,b,c,d)
+#define IStillImage_GetDeviceValue(p,a,b,c,d,e)         (p)->GetDeviceValue(a,b,c,d,e)
+#define IStillImage_SetDeviceValue(p,a,b,c,d,e)         (p)->SetDeviceValue(a,b,c,d,e)
+#define IStillImage_GetSTILaunchInformation(p,a,b,c)    (p)->GetSTILaunchInformation(a,b,c)
+#define IStillImage_RegisterLaunchApplication(p,a,b)    (p)->RegisterLaunchApplication(a,b)
+#define IStillImage_UnregisterLaunchApplication(p,a)    (p)->UnregisterLaunchApplication(a)
+#define IStillImage_EnableHwNotifications(p,a,b)        (p)->EnableHwNotifications(a,b)
+#define IStillImage_GetHwNotificationState(p,a,b)       (p)->GetHwNotificationState(a,b)
+#define IStillImage_RefreshDeviceBus(p,a)               (p)->RefreshDeviceBus(a)
+#define IStillImage_LaunchApplicationForDevice(p,a,b,c) (p)->LaunchApplicationForDevice(a,b,c)
+#define IStillImage_SetupDeviceParameters(p,a)          (p)->SetupDeviceParameters(a)
+#define IStillImage_WriteToErrorLog(p,a,b)              (p)->WriteToErrorLog(a,b)
+#endif
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/include/psdk/strsafe.h b/include/psdk/strsafe.h
new file mode 100644 (file)
index 0000000..7f09e1b
--- /dev/null
@@ -0,0 +1,626 @@
+#ifndef __STRSAFE_H_
+#define __STRSAFE_H_
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#if defined(STRSAFE_NO_CCH_FUNCTIONS) && defined(STRSAFE_NO_CB_FUNCTIONS)
+#error Both STRSAFE_NO_CCH_FUNCTIONS and STRSAFE_NO_CB_FUNCTIONS are defined
+#endif
+
+#ifndef SUCCEEDED
+#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)
+#endif
+#define STRSAFE_MAX_CCH 2147483647
+#define STRSAFE_E_INVALID_PARAMETER ((HRESULT)0x80070057L)
+#define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL)
+#define STRSAFE_E_END_OF_FILE ((HRESULT)0x80070026L)
+
+#define STRSAFE_FILL_BEHIND_NULL 0x00000200
+#define STRSAFE_IGNORE_NULLS 0x00000200
+#define STRSAFE_FILL_ON_FAILURE 0x00000400
+#define STRSAFE_NULL_ON_FAILURE 0x00000800
+#define STRSAFE_NO_TRUNCATION 0x00001000
+
+#ifndef S_OK
+#define S_OK  ((HRESULT)0x00000000L)
+#endif
+
+#define STRSAFE_MIN(a,b) (((a) < (b))?(a):(b))
+
+#ifndef _HRESULT_DEFINED
+#define _HRESULT_DEFINED
+typedef long HRESULT;
+#endif
+
+typedef char * STRSAFE_LPSTR;
+typedef const char * STRSAFE_LPCSTR;
+typedef wchar_t * STRSAFE_LPWSTR;
+typedef const wchar_t * STRSAFE_LPCWSTR;
+typedef unsigned long STRSAFE_DWORD;
+
+#define STRSAFE_PASS2
+
+/* Implement Cb functions for ansi and unicode */
+#ifndef STRSAFE_NO_CB_FUNCTIONS
+#define STRSAFE_CB
+#define STRSAFE_UNICODE 0
+# include <strsafe.h>
+#undef STRSAFE_UNICODE
+#define STRSAFE_UNICODE 1
+# include <strsafe.h>
+#undef STRSAFE_UNICODE
+#undef STRSAFE_CB
+#endif // !STRSAFE_NO_CB_FUNCTIONS
+
+/* Implement Cch functions for ansi and unicode */
+#ifndef STRSAFE_NO_CCH_FUNCTIONS
+#define STRSAFE_UNICODE 0
+# include <strsafe.h>
+#undef STRSAFE_UNICODE
+#define STRSAFE_UNICODE 1
+# include <strsafe.h>
+#undef STRSAFE_UNICODE
+#endif // !STRSAFE_NO_CCH_FUNCTIONS
+
+#undef STRSAFE_PASS2
+
+/* Now define the functions depending on UNICODE */
+#if defined(UNICODE)
+# define STRSAFE_UNICODE 1
+#else
+# define STRSAFE_UNICODE 0
+#endif
+#include <strsafe.h>
+#undef STRSAFE_UNICODE
+
+#endif // !__STRSAFE_H_
+
+/*****************************************************************************/
+
+#if defined(STRSAFE_UNICODE)
+#if (STRSAFE_UNICODE == 1)
+
+#define STRSAFE_LPTSTR STRSAFE_LPWSTR
+#define STRSAFE_LPCTSTR STRSAFE_LPCWSTR
+#define STRSAFE_TCHAR wchar_t
+
+#define StringCbCat StringCbCatW
+#define StringCbCatEx StringCbCatExW
+#define StringCbCatN StringCbCatNW
+#define StringCbCatNEx StringCbCatNExW
+#define StringCbCatWorker StringCxxCatWorkerW
+#define StringCbCopy StringCbCopyW
+#define StringCbCopyEx StringCbCopyExW
+#define StringCbCopyN StringCbCopyNW
+#define StringCbCopyNEx StringCbCopyNExW
+#define StringCbGets StringCbGetsW
+#define StringCbGetsEx StringCbGetsExW
+#define StringCbLength StringCbLengthW
+#define StringCbPrintf StringCbPrintfW
+#define StringCbPrintfEx StringCbPrintfExW
+#define StringCbVPrintf StringCbVPrintfW
+#define StringCbVPrintfEx StringCbVPrintfExW
+#define StringCchCat StringCchCatW
+#define StringCchCatEx StringCchCatExW
+#define StringCchCatN StringCchCatNW
+#define StringCchCatNEx StringCchCatNExW
+#define StringCchCatWorker StringCchCatWorkerW
+#define StringCchCopy StringCchCopyW
+#define StringCchCopyEx StringCchCopyExW
+#define StringCchCopyN StringCchCopyNW
+#define StringCchCopyNEx StringCchCopyNExW
+#define StringCchGets StringCchGetsW
+#define StringCchGetsEx StringCchGetsExW
+#define StringCchLength StringCchLengthW
+#define StringCchPrintf StringCchPrintfW
+#define StringCchPrintfEx StringCchPrintfExW
+#define StringCchVPrintf StringCchVPrintfW
+#define StringCchVPrintfEx StringCchVPrintfExW
+#define _vsnprintfAW _vsnwprintf
+
+#else // (STRSAFE_UNICODE != 1)
+
+#define STRSAFE_LPTSTR STRSAFE_LPSTR
+#define STRSAFE_LPCTSTR STRSAFE_LPCSTR
+#define STRSAFE_TCHAR char
+
+#define StringCbCat StringCbCatA
+#define StringCbCatEx StringCbCatExA
+#define StringCbCatN StringCbCatNA
+#define StringCbCatNEx StringCbCatNExA
+#define StringCbCatWorker StringCxxCatWorkerA
+#define StringCbCopy StringCbCopyA
+#define StringCbCopyEx StringCbCopyExA
+#define StringCbCopyN StringCbCopyNA
+#define StringCbCopyNEx StringCbCopyNExA
+#define StringCbGets StringCbGetsA
+#define StringCbGetsEx StringCbGetsExA
+#define StringCbLength StringCbLengthA
+#define StringCbPrintf StringCbPrintfA
+#define StringCbPrintfEx StringCbPrintfExA
+#define StringCbVPrintf StringCbVPrintfA
+#define StringCbVPrintfEx StringCbVPrintfExA
+#define StringCchCat StringCchCatA
+#define StringCchCatEx StringCchCatExA
+#define StringCchCatN StringCchCatNA
+#define StringCchCatNEx StringCchCatNExA
+#define StringCchCatWorker StringCchCatWorkerA
+#define StringCchCopy StringCchCopyA
+#define StringCchCopyEx StringCchCopyExA
+#define StringCchCopyN StringCchCopyNA
+#define StringCchCopyNEx StringCchCopyNExA
+#define StringCchGets StringCchGetsA
+#define StringCchGetsEx StringCchGetsExA
+#define StringCchLength StringCchLengthA
+#define StringCchPrintf StringCchPrintfA
+#define StringCchPrintfEx StringCchPrintfExA
+#define StringCchVPrintf StringCchVPrintfA
+#define StringCchVPrintfEx StringCchVPrintfExA
+#define _vsnprintfAW _vsnprintf
+
+#endif // (STRSAFE_UNICODE != 1)
+#endif // defined(STRSAFE_UNICODE)
+
+/*****************************************************************************/
+
+#if defined (STRSAFE_PASS2)
+
+#if defined(STRSAFE_CB)
+
+#define STRSAFE_CXXtoCB(x) (x)
+#define STRSAFE_CBtoCXX(x) (x)
+#define STRSAFE_CXXtoCCH(x) (x)/sizeof(STRSAFE_TCHAR)
+#define STRSAFE_CCHtoCXX(x) (x)*sizeof(STRSAFE_TCHAR)
+#define StringCxxCat StringCbCat
+#define StringCxxCatEx StringCbCatEx
+#define StringCxxCatN StringCbCatN
+#define StringCxxCatNEx StringCbCatNEx
+#define StringCxxCatWorker StringCbCatWorker
+#define StringCxxCopy StringCbCopy
+#define StringCxxCopyEx StringCbCopyEx
+#define StringCxxCopyN StringCbCopyN
+#define StringCxxCopyNEx StringCbCopyNEx
+#define StringCxxGets StringCbGets
+#define StringCxxGetsEx StringCbGetsEx
+#define StringCxxLength StringCbLength
+#define StringCxxPrintf StringCbPrintf
+#define StringCxxPrintfEx StringCbPrintfEx
+#define StringCxxVPrintf StringCbVPrintf
+#define StringCxxVPrintfEx StringCbVPrintfEx
+
+#else // !STRSAFE_CB
+
+#define STRSAFE_CXXtoCB(x) (x)*sizeof(STRSAFE_TCHAR)
+#define STRSAFE_CBtoCXX(x) (x)/sizeof(STRSAFE_TCHAR)
+#define STRSAFE_CXXtoCCH(x) (x)
+#define STRSAFE_CCHtoCXX(x) (x)
+#define StringCxxCat StringCchCat
+#define StringCxxCatEx StringCchCatEx
+#define StringCxxCatN StringCchCatN
+#define StringCxxCatNEx StringCchCatNEx
+#define StringCxxCatWorker StringCchCatWorker
+#define StringCxxCopy StringCchCopy
+#define StringCxxCopyEx StringCchCopyEx
+#define StringCxxCopyN StringCchCopyN
+#define StringCxxCopyNEx StringCchCopyNEx
+#define StringCxxGets StringCchGets
+#define StringCxxGetsEx StringCchGetsEx
+#define StringCxxLength StringCchLength
+#define StringCxxPrintf StringCchPrintf
+#define StringCxxPrintfEx StringCchPrintfEx
+#define StringCxxVPrintf StringCchVPrintf
+#define StringCxxVPrintfEx StringCchVPrintfEx
+
+#endif // !STRSAFE_CB
+
+#ifdef STRSAFE_LIB
+
+/* Normal function prototypes only */
+#define STRSAFEAPI HRESULT __stdcall
+
+STRSAFEAPI StringCxxCat(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc);
+STRSAFEAPI StringCxxCatEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags);
+STRSAFEAPI StringCxxCatN(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbMaxAppend);
+STRSAFEAPI StringCxxCatNEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbMaxAppend, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags);
+STRSAFEAPI StringCxxCopy(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc);
+STRSAFEAPI StringCxxCopyEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags);
+STRSAFEAPI StringCxxCopyN(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbSrc);
+STRSAFEAPI StringCxxCopyNEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszSrc, size_t cbSrc, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags);
+STRSAFEAPI StringCxxGets(STRSAFE_LPTSTR pszDest, size_t cxDest);
+STRSAFEAPI StringCxxGetsEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags);
+STRSAFEAPI StringCxxLength(STRSAFE_LPCTSTR psz, size_t cxMax, size_t *pcb);
+STRSAFEAPI StringCxxPrintf(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszFormat, ...);
+STRSAFEAPI StringCxxPrintfEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags, STRSAFE_LPCTSTR pszFormat, ...);
+STRSAFEAPI StringCxxVPrintf(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPCTSTR pszFormat, va_list args);
+STRSAFEAPI StringCxxVPrintfEx(STRSAFE_LPTSTR pszDest, size_t cxDest, STRSAFE_LPTSTR *ppszDestEnd, size_t *pcbRemaining, STRSAFE_DWORD dwFlags, LPCTSTR pszFormat, va_list args);
+
+#else // !STRSAFE_LIB
+
+/* Create inlined versions */
+#define STRSAFEAPI HRESULT static __inline__
+
+#define STRSAFE_MAX_CXX STRSAFE_CCHtoCXX(STRSAFE_MAX_CCH)
+
+STRSAFEAPI
+StringCxxCatWorker(
+    STRSAFE_LPTSTR pszDest,
+    size_t cxDest,
+    STRSAFE_LPCTSTR pszSrc,
+    size_t cxMaxAppend,
+    STRSAFE_LPTSTR *ppszDestEnd,
+    size_t *pcbRemaining,
+    STRSAFE_DWORD dwFlags,
+    int UseN)
+{
+    HRESULT result;
+    STRSAFE_LPTSTR psz = pszDest;
+    size_t cch = STRSAFE_CXXtoCCH(cxDest);
+
+    if (!pszDest || !pszSrc || cxDest > STRSAFE_MAX_CXX || cxDest == 0)
+    {
+        return STRSAFE_E_INVALID_PARAMETER;
+    }
+
+    for (--psz; *(++psz) != 0 && --cch > 0;);
+    if (cch == 0)
+    {
+        return STRSAFE_E_INSUFFICIENT_BUFFER;
+    }
+
+    if (UseN)
+    {
+        cch = STRSAFE_MIN(cxDest, STRSAFE_CXXtoCCH(cxMaxAppend));
+    }
+
+    for (--pszSrc, --psz; (*(++psz) = *(++pszSrc)) != 0 && --cch > 0;);
+    if (cch == 0)
+    {
+        result = STRSAFE_E_INSUFFICIENT_BUFFER;
+    }
+    else
+        result = S_OK;
+
+    if (ppszDestEnd)
+    {
+        *ppszDestEnd = psz;
+    }
+
+    if (pcbRemaining)
+    {
+        *pcbRemaining = STRSAFE_CCHtoCXX(cch);
+    }
+
+    if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
+    {
+        for (--psz, ++cch; --cch; *(++psz) = dwFlags & 0xff);
+    }
+
+    if (!SUCCEEDED(result))
+    {
+        if (dwFlags & STRSAFE_FILL_ON_FAILURE)
+        {
+           cch = STRSAFE_CXXtoCCH(cxDest);
+           for (--pszDest, ++cch; --cch; *(++pszDest) = dwFlags & 0xff);
+        }
+
+        if (dwFlags & STRSAFE_NULL_ON_FAILURE)
+        {
+            *pszDest = 0;
+        }
+    }
+
+    return result;
+}
+
+STRSAFEAPI
+StringCxxCatEx(
+    STRSAFE_LPTSTR pszDest,
+    size_t cxDest,
+    STRSAFE_LPCTSTR pszSrc,
+    STRSAFE_LPTSTR *ppszDestEnd,
+    size_t *pcbRemaining,
+    STRSAFE_DWORD dwFlags)
+{
+    return StringCxxCatWorker(pszDest, cxDest, pszSrc, 0, ppszDestEnd, pcbRemaining, dwFlags, 0);
+}
+
+STRSAFEAPI
+StringCxxCat(
+    STRSAFE_LPTSTR pszDest,
+    size_t cxDest,
+    STRSAFE_LPCTSTR pszSrc)
+{
+    return StringCxxCatWorker(pszDest, cxDest, pszSrc, 0, NULL, NULL, 0, 0);
+}
+
+STRSAFEAPI
+StringCxxCatN(
+    STRSAFE_LPTSTR pszDest,
+    size_t cxDest,
+    STRSAFE_LPCTSTR pszSrc,
+    size_t cbMaxAppend)
+{
+    return StringCxxCatWorker(pszDest, cxDest, pszSrc, cbMaxAppend, NULL, NULL, 0, 1);
+}
+
+STRSAFEAPI
+StringCxxCatNEx(
+    STRSAFE_LPTSTR pszDest,
+    size_t cxDest,
+    STRSAFE_LPCTSTR pszSrc,
+    size_t cbMaxAppend,
+    STRSAFE_LPTSTR *ppszDestEnd,
+    size_t *pcbRemaining,
+    STRSAFE_DWORD dwFlags)
+{
+    return StringCxxCatWorker(pszDest, cxDest, pszSrc, cbMaxAppend, ppszDestEnd, pcbRemaining, dwFlags, 1);
+}
+
+STRSAFEAPI
+StringCxxCopy(
+    STRSAFE_LPTSTR pszDest,
+    size_t cbDest,
+    STRSAFE_LPCTSTR pszSrc)
+{
+    return 0; // FIXME
+}
+
+STRSAFEAPI
+StringCxxCopyEx(
+    STRSAFE_LPTSTR pszDest,
+    size_t cbDest,
+    STRSAFE_LPCTSTR pszSrc,
+    STRSAFE_LPTSTR *ppszDestEnd,
+    size_t *pcbRemaining,
+    STRSAFE_DWORD dwFlags)
+{
+    return 0; // FIXME
+}
+
+STRSAFEAPI
+StringCxxCopyN(
+    STRSAFE_LPTSTR pszDest,
+    size_t cbDest,
+    STRSAFE_LPCTSTR pszSrc,
+    size_t cbSrc)
+{
+    return 0; // FIXME
+}
+
+STRSAFEAPI
+StringCxxCopyNEx(
+    STRSAFE_LPTSTR pszDest,
+    size_t cbDest,
+    STRSAFE_LPCTSTR pszSrc,
+    size_t cbSrc,
+    STRSAFE_LPTSTR *ppszDestEnd,
+    size_t *pcbRemaining,
+    STRSAFE_DWORD dwFlags)
+{
+    return 0; // FIXME
+}
+
+STRSAFEAPI
+StringCxxGets(
+    STRSAFE_LPTSTR pszDest,
+    size_t cbDest)
+{
+    return 0; // FIXME
+}
+
+STRSAFEAPI
+StringCxxGetsEx(
+    STRSAFE_LPTSTR pszDest,
+    size_t cbDest,
+    STRSAFE_LPTSTR *ppszDestEnd,
+    size_t *pcbRemaining,
+    STRSAFE_DWORD dwFlags)
+{
+    return 0; // FIXME
+}
+
+STRSAFEAPI
+StringCxxLength(
+    STRSAFE_LPCTSTR psz,
+    size_t cxMax,
+    size_t *pcx)
+{
+    size_t cch = STRSAFE_CXXtoCCH(cxMax);
+
+    /* Default return on error */
+    if (pcx)
+        *pcx = 0;
+
+    if (!psz || cxMax > STRSAFE_MAX_CXX || cxMax == 0)
+    {
+        return STRSAFE_E_INVALID_PARAMETER;
+    }
+
+    for (--psz; *(++psz) != 0 && --cch > 0;);
+
+    if (cch == 0)
+    {
+        return STRSAFE_E_INVALID_PARAMETER;
+    }
+
+    if (pcx)
+        *pcx = cxMax - STRSAFE_CCHtoCXX(cch);
+
+    return S_OK;
+}
+
+STRSAFEAPI
+StringCxxVPrintfEx(
+    STRSAFE_LPTSTR pszDest,
+    size_t cxDest,
+    STRSAFE_LPTSTR *ppszDestEnd,
+    size_t *pcxRemaining,
+    STRSAFE_DWORD dwFlags,
+    STRSAFE_LPCTSTR pszFormat,
+    va_list args)
+{
+    size_t cchDest = STRSAFE_CXXtoCCH(cxDest);
+    size_t cchMax = cchDest - 1;
+    int iResult;
+    HRESULT hr;
+
+    if (dwFlags & STRSAFE_IGNORE_NULLS)
+    {
+        if (!pszDest) pszDest = (STRSAFE_LPTSTR)L"";
+        if (!pszFormat) pszFormat = (STRSAFE_LPTSTR)L"";
+    }
+
+    if (!pszDest || !pszFormat || cxDest > STRSAFE_MAX_CXX || cxDest == 0)
+    {
+        return STRSAFE_E_INVALID_PARAMETER;
+    }
+
+#if (STRSAFE_USE_SECURE_CRT == 1)
+    iResult = _vsnprintf_sAW(pszDest, cchDest, cchMax, pszFormat, args);
+#else
+    iResult = _vsnprintfAW(pszDest, cchMax, pszFormat, args);
+#endif
+
+    hr = (iResult == -1) ? STRSAFE_E_INSUFFICIENT_BUFFER : S_OK;
+
+    if ((size_t)iResult >= cchMax)
+    {
+        pszDest[cchMax] = 0;
+        iResult = cchMax;
+    }
+
+    if (ppszDestEnd) *ppszDestEnd = pszDest + iResult;
+
+    if (pcxRemaining) *pcxRemaining = STRSAFE_CCHtoCXX(cchMax - iResult);
+
+    if (SUCCEEDED(hr))
+    {
+        if ((dwFlags & STRSAFE_FILL_BEHIND_NULL) && (iResult + 1 < cchMax))
+        {
+            memset(pszDest + iResult + 1,
+                   dwFlags & 0xff,
+                   (cchMax - iResult - 1) * sizeof(STRSAFE_TCHAR));
+        }
+    }
+    else
+    {
+        if (dwFlags & STRSAFE_FILL_ON_FAILURE)
+        {
+            memset(pszDest, dwFlags & 0xff, cchMax * sizeof(STRSAFE_TCHAR));
+        }
+        else if (dwFlags & STRSAFE_NULL_ON_FAILURE)
+        {
+            *pszDest = 0;
+        }
+    }
+
+    return hr;
+}
+
+STRSAFEAPI
+StringCxxVPrintf(
+    STRSAFE_LPTSTR pszDest,
+    size_t cxDest,
+    STRSAFE_LPCTSTR pszFormat,
+    va_list args)
+{
+    return StringCxxVPrintfEx(pszDest, cxDest, NULL, NULL, 0, pszFormat, args);
+}
+
+STRSAFEAPI
+StringCxxPrintf(
+    STRSAFE_LPTSTR pszDest,
+    size_t cxDest,
+    STRSAFE_LPCTSTR pszFormat, ...)
+{
+    HRESULT result;
+    va_list args;
+    va_start(args, pszFormat);
+    result = StringCxxVPrintf(pszDest, cxDest, pszFormat, args);
+    va_end(args);
+    return result;
+}
+
+STRSAFEAPI
+StringCxxPrintfEx(
+    STRSAFE_LPTSTR pszDest,
+    size_t cxDest,
+    STRSAFE_LPTSTR *ppszDestEnd,
+    size_t *pcbRemaining,
+    STRSAFE_DWORD dwFlags,
+    STRSAFE_LPCTSTR pszFormat, ...)
+{
+    HRESULT result;
+    va_list args;
+    va_start(args, pszFormat);
+    result = StringCxxVPrintfEx(pszDest, cxDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, args);
+    va_end(args);
+    return result;
+}
+
+#endif // !STRSAFE_LIB
+
+/* Functions are implemented or defined, clear #defines for next pass */
+#undef StringCxxCat
+#undef StringCxxCatEx
+#undef StringCxxCatN
+#undef StringCxxCatNEx
+#undef StringCxxCatWorker
+#undef StringCxxCopy
+#undef StringCxxCopyEx
+#undef StringCxxCopyN
+#undef StringCxxCopyNEx
+#undef StringCxxGets
+#undef StringCxxGetsEx
+#undef StringCxxLength
+#undef StringCxxPrintf
+#undef StringCxxPrintfEx
+#undef StringCxxVPrintf
+#undef StringCxxVPrintfEx
+
+#undef StringCbCat
+#undef StringCbCatEx
+#undef StringCbCatN
+#undef StringCbCatNEx
+#undef StringCbCatWorker
+#undef StringCbCopy
+#undef StringCbCopyEx
+#undef StringCbCopyN
+#undef StringCbCopyNEx
+#undef StringCbGets
+#undef StringCbGetsEx
+#undef StringCbLength
+#undef StringCbPrintf
+#undef StringCbPrintfEx
+#undef StringCbVPrintf
+#undef StringCbVPrintfEx
+#undef StringCchCat
+#undef StringCchCatEx
+#undef StringCchCatN
+#undef StringCchCatNEx
+#undef StringCchCatWorker
+#undef StringCchCopy
+#undef StringCchCopyEx
+#undef StringCchCopyN
+#undef StringCchCopyNEx
+#undef StringCchGets
+#undef StringCchGetsEx
+#undef StringCchLength
+#undef StringCchPrintf
+#undef StringCchPrintfEx
+#undef StringCchVPrintf
+#undef StringCchVPrintfEx
+#undef _vsnprintfAW
+
+#undef STRSAFE_LPTSTR
+#undef STRSAFE_LPCTSTR
+#undef STRSAFE_TCHAR
+
+#undef STRSAFE_CXXtoCB
+#undef STRSAFE_CBtoCXX
+#undef STRSAFE_CXXtoCCH
+#undef STRSAFE_CCHtoCXX
+
+#endif // defined (STRSAFE_PASS2)
+
diff --git a/include/psdk/wia.h b/include/psdk/wia.h
new file mode 100644 (file)
index 0000000..3a0497e
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009 Damjan Jovanovic
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifdef __WINESRC__
+#error Specify wia_lh.h or wia_xp.h explicitly in Wine
+#endif
+
+#if (_WIN32_WINNT >= 0x0600)
+#include <wia_lh.h>
+#elif (_WIN32_WINNT >= 0x0501)
+#include <wia_xp.h>
+#endif
diff --git a/include/psdk/wia_lh.idl b/include/psdk/wia_lh.idl
new file mode 100644 (file)
index 0000000..5024787
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2009 Damjan Jovanovic
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+import "wtypes.idl";
+import "objidl.idl";
+
+interface IEnumWIA_DEV_INFO;
+interface IWiaItem;
+interface IWiaEventCallback;
+
+cpp_quote("DEFINE_GUID(CLSID_WiaDevMgr, 0xa1f4e726,0x8cf1,0x11d1,0xbf,0x92,0x00,0x60,0x08,0x1e,0xd8,0x11);")
+
+[
+    object,
+    uuid(5eb2502a-8cf1-11d1-bf92-0060081ed811)
+]
+interface IWiaDevMgr : IUnknown
+{
+    HRESULT EnumDeviceInfo(
+        [in] LONG lFlag,
+        [retval, out] IEnumWIA_DEV_INFO **ppIEnum);
+
+    HRESULT CreateDevice(
+        [in] BSTR bstrDeviceID,
+        [out] IWiaItem **ppWiaItemRoot);
+
+    HRESULT SelectDeviceDlg(
+        [in] HWND hwndParent,
+        [in] LONG lDeviceType,
+        [in] LONG lFlags,
+        [in, out] BSTR *pbstrDeviceID,
+        [retval, out] IWiaItem **ppItemRoot);
+
+    HRESULT SelectDeviceDlgID(
+        [in] HWND hwndParent,
+        [in] LONG lDeviceType,
+        [in] LONG lFlags,
+        [retval, out] BSTR *pbstrDeviceID);
+
+    HRESULT GetImageDlg(
+        [in] HWND hwndParent,
+        [in] LONG lDeviceType,
+        [in] LONG lFlags,
+        [in] LONG lIntent,
+        [in] IWiaItem *pItemRoot,
+        [in] BSTR bstrFilename,
+        [in, out] GUID *pguidFormat);
+
+    HRESULT RegisterEventCallbackProgram(
+        [in] LONG lFlags,
+        [in] BSTR bstrDeviceID,
+        [in] const GUID *pEventGUID,
+        [in] BSTR bstrCommandline,
+        [in] BSTR bstrName,
+        [in] BSTR bstrDescription,
+        [in] BSTR bstrIcon);
+
+    HRESULT RegisterEventCallbackInterface(
+        [in] LONG lFlags,
+        [in] BSTR bstrDeviceID,
+        [in] const GUID *pEventGUID,
+        [unique, in] IWiaEventCallback *pIWiaEventCallback,
+        [out] IUnknown **pEventObject);
+
+    HRESULT RegisterEventCallbackCLSID(
+        [in] LONG lFlags,
+        [in] BSTR bstrDeviceID,
+        [in] const GUID *pEventGUID,
+        [unique, in] const GUID *pClsID,
+        [in] BSTR bstrName,
+        [in] BSTR bstrDescription,
+        [in] BSTR bstrIcon);
+
+    HRESULT AddDeviceDlg(
+        [in] HWND hwndParent,
+        [in] LONG lFlags);
+}
+
+[
+    object,
+    uuid(5e38b83c-8cf1-11d1-bf92-0060081ed811)
+]
+interface IEnumWIA_DEV_INFO : IUnknown
+{
+    /* fill in */
+}
+
+[
+    object,
+    uuid(4db1ad10-3391-11d2-9a33-00c04fa36145)
+]
+interface IWiaItem : IUnknown
+{
+    /* FIXME: fill in */
+}
+
+[
+    object,
+    uuid(ae6287b0-0084-11d2-973b-00a0c9068f2e)
+]
+interface IWiaEventCallback : IUnknown
+{
+    HRESULT ImageEventCallback(
+        [in] const GUID *pEventGUID,
+        [in] BSTR bstrEventDescription,
+        [in] BSTR bstrDeviceID,
+        [in] BSTR bstrDeviceDescription,
+        [in] DWORD dwDeviceType,
+        [in] BSTR bstrFullItemName,
+        [in,out] ULONG *pulEventType,
+        [in] ULONG ulReserved);
+}
diff --git a/include/psdk/wia_xp.idl b/include/psdk/wia_xp.idl
new file mode 100644 (file)
index 0000000..5024787
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2009 Damjan Jovanovic
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+import "wtypes.idl";
+import "objidl.idl";
+
+interface IEnumWIA_DEV_INFO;
+interface IWiaItem;
+interface IWiaEventCallback;
+
+cpp_quote("DEFINE_GUID(CLSID_WiaDevMgr, 0xa1f4e726,0x8cf1,0x11d1,0xbf,0x92,0x00,0x60,0x08,0x1e,0xd8,0x11);")
+
+[
+    object,
+    uuid(5eb2502a-8cf1-11d1-bf92-0060081ed811)
+]
+interface IWiaDevMgr : IUnknown
+{
+    HRESULT EnumDeviceInfo(
+        [in] LONG lFlag,
+        [retval, out] IEnumWIA_DEV_INFO **ppIEnum);
+
+    HRESULT CreateDevice(
+        [in] BSTR bstrDeviceID,
+        [out] IWiaItem **ppWiaItemRoot);
+
+    HRESULT SelectDeviceDlg(
+        [in] HWND hwndParent,
+        [in] LONG lDeviceType,
+        [in] LONG lFlags,
+        [in, out] BSTR *pbstrDeviceID,
+        [retval, out] IWiaItem **ppItemRoot);
+
+    HRESULT SelectDeviceDlgID(
+        [in] HWND hwndParent,
+        [in] LONG lDeviceType,
+        [in] LONG lFlags,
+        [retval, out] BSTR *pbstrDeviceID);
+
+    HRESULT GetImageDlg(
+        [in] HWND hwndParent,
+        [in] LONG lDeviceType,
+        [in] LONG lFlags,
+        [in] LONG lIntent,
+        [in] IWiaItem *pItemRoot,
+        [in] BSTR bstrFilename,
+        [in, out] GUID *pguidFormat);
+
+    HRESULT RegisterEventCallbackProgram(
+        [in] LONG lFlags,
+        [in] BSTR bstrDeviceID,
+        [in] const GUID *pEventGUID,
+        [in] BSTR bstrCommandline,
+        [in] BSTR bstrName,
+        [in] BSTR bstrDescription,
+        [in] BSTR bstrIcon);
+
+    HRESULT RegisterEventCallbackInterface(
+        [in] LONG lFlags,
+        [in] BSTR bstrDeviceID,
+        [in] const GUID *pEventGUID,
+        [unique, in] IWiaEventCallback *pIWiaEventCallback,
+        [out] IUnknown **pEventObject);
+
+    HRESULT RegisterEventCallbackCLSID(
+        [in] LONG lFlags,
+        [in] BSTR bstrDeviceID,
+        [in] const GUID *pEventGUID,
+        [unique, in] const GUID *pClsID,
+        [in] BSTR bstrName,
+        [in] BSTR bstrDescription,
+        [in] BSTR bstrIcon);
+
+    HRESULT AddDeviceDlg(
+        [in] HWND hwndParent,
+        [in] LONG lFlags);
+}
+
+[
+    object,
+    uuid(5e38b83c-8cf1-11d1-bf92-0060081ed811)
+]
+interface IEnumWIA_DEV_INFO : IUnknown
+{
+    /* fill in */
+}
+
+[
+    object,
+    uuid(4db1ad10-3391-11d2-9a33-00c04fa36145)
+]
+interface IWiaItem : IUnknown
+{
+    /* FIXME: fill in */
+}
+
+[
+    object,
+    uuid(ae6287b0-0084-11d2-973b-00a0c9068f2e)
+]
+interface IWiaEventCallback : IUnknown
+{
+    HRESULT ImageEventCallback(
+        [in] const GUID *pEventGUID,
+        [in] BSTR bstrEventDescription,
+        [in] BSTR bstrDeviceID,
+        [in] BSTR bstrDeviceDescription,
+        [in] DWORD dwDeviceType,
+        [in] BSTR bstrFullItemName,
+        [in,out] ULONG *pulEventType,
+        [in] ULONG ulReserved);
+}
index 6b38dac..79c52ac 100644 (file)
@@ -2301,6 +2301,9 @@ VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE);
 VOID WINAPI WakeAllConditionVariable(PCONDITION_VARIABLE);
 #endif
 BOOL WINAPI WinLoadTrustProvider(GUID*);
+BOOL WINAPI Wow64DisableWow64FsRedirection(PVOID*);
+BOOLEAN WINAPI Wow64EnableWow64FsRedirection(BOOLEAN);
+BOOL WINAPI Wow64RevertWow64FsRedirection(PVOID);
 BOOL WINAPI WriteFile(HANDLE,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED);
 BOOL WINAPI WriteFileEx(HANDLE,LPCVOID,DWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE);
 BOOL WINAPI WriteFileGather(HANDLE,FILE_SEGMENT_ELEMENT*,DWORD,LPDWORD,LPOVERLAPPED);
index edfbae6..cad35c7 100644 (file)
@@ -3050,7 +3050,9 @@ UINT WINAPI GetEnhMetaFilePaletteEntries(HENHMETAFILE,UINT,LPPALETTEENTRY);
 UINT WINAPI GetEnhMetaFilePixelFormat(HENHMETAFILE,UINT,PIXELFORMATDESCRIPTOR*);
 DWORD WINAPI GetFontData(HDC,DWORD,DWORD,PVOID,DWORD);
 DWORD WINAPI GetFontLanguageInfo(HDC);
+#if (_WIN32_WINNT >= 0x0500)
 DWORD WINAPI GetFontUnicodeRanges(HDC,LPGLYPHSET);
+#endif
 DWORD WINAPI GetGlyphIndicesA(HDC,LPCSTR,INT,LPWORD,DWORD);
 DWORD WINAPI GetGlyphIndicesW(HDC,LPCWSTR,INT,LPWORD,DWORD);
 DWORD WINAPI GetGlyphOutlineA(HDC,UINT,UINT,LPGLYPHMETRICS,DWORD,PVOID,const MAT2*);
index f856b07..66c94b2 100644 (file)
@@ -63,6 +63,14 @@ extern "C" {
 #define UNALIGNED
 #endif
 
+#ifndef DECLSPEC_NOVTABLE
+# if defined(_MSC_VER) && (_MSC_VER >= 1100) && defined(__cplusplus)
+#  define DECLSPEC_NOVTABLE __declspec(novtable)
+# else
+#  define DECLSPEC_NOVTABLE
+# endif
+#endif
+
 #ifndef DECLSPEC_ADDRSAFE
 #if (_MSC_VER >= 1200) && (defined(_M_ALPHA) || defined(_M_AXP64))
 #define DECLSPEC_ADDRSAFE __declspec(address_safe)
index bea47d1..21cdf04 100644 (file)
@@ -4442,7 +4442,7 @@ int WINAPI SetScrollInfo(HWND,int,LPCSCROLLINFO,BOOL);
 int WINAPI SetScrollPos(HWND,int,int,BOOL);
 BOOL WINAPI SetScrollRange(HWND,int,int,int,BOOL);
 BOOL WINAPI SetSysColors(int,const INT *,const COLORREF *);
-DWORD WINAPI SetSysColorsTemp(const COLORREF *, const HBRUSH *, DWORD);
+DWORD_PTR WINAPI SetSysColorsTemp(const COLORREF *, const HBRUSH *, DWORD_PTR);
 #define SetSysModalWindow(h) (NULL)
 BOOL WINAPI SetSystemCursor(HCURSOR,DWORD);
 BOOL WINAPI SetSystemMenu(HWND,HMENU);
index 68262c2..82e6d9f 100644 (file)
@@ -54,13 +54,16 @@ extern ULONG_PTR MmUserProbeAddress;
 //
 #define MAXIMUM_VECTOR          16
 
+#define KERNEL_STACK_SIZE                   12288
+#define KERNEL_LARGE_STACK_SIZE             61440
+#define KERNEL_LARGE_STACK_COMMIT           12288
 
 //
 // Used to contain PFNs and PFN counts
 //
-typedef ULONG PFN_COUNT;
-typedef ULONG PFN_NUMBER, *PPFN_NUMBER;
-typedef LONG SPFN_NUMBER, *PSPFN_NUMBER;
+//typedef ULONG PFN_COUNT;
+//typedef ULONG PFN_NUMBER, *PPFN_NUMBER;
+//typedef LONG SPFN_NUMBER, *PSPFN_NUMBER;
 
 //
 // Stub
@@ -124,11 +127,25 @@ typedef struct _CONTEXT {
 #ifdef _WINNT_H
 #define KIRQL ULONG
 #endif
+
+typedef struct _NT_TIB_KPCR {
+       struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
+       PVOID StackBase;
+       PVOID StackLimit;
+       PVOID SubSystemTib;
+       _ANONYMOUS_UNION union {
+               PVOID FiberData;
+               ULONG Version;
+       } DUMMYUNIONNAME;
+       PVOID ArbitraryUserPointer;
+       struct _NT_TIB_KPCR *Self;
+} NT_TIB_KPCR,*PNT_TIB_KPCR;
+
 typedef struct _KPCR
 {
     union
     {
-        NT_TIB NtTib;
+        NT_TIB_KPCR NtTib;
         struct
         {
             struct _EXCEPTION_REGISTRATION_RECORD *Used_ExceptionList; // Unused
@@ -167,6 +184,11 @@ struct _TEB* NtCurrentTeb(VOID)
     return (struct _TEB*)USERPCR->Used_Self;
 }
 
+NTSYSAPI
+PKTHREAD
+NTAPI
+KeGetCurrentThread(VOID);
+
 #ifndef _WINNT_H
 //
 // IRQL Support on ARM is similar to MIPS/ALPHA
index 30afca4..f60a37c 100644 (file)
@@ -73,7 +73,7 @@ ENDM
 .altmacro
 
 /* Hex numbers need to be in 0x1AB format */
-#define HEX(x) 0x##x
+#define HEX(y) 0x##y
 
 /* Macro values need to be marked */
 #define VAL(x) \x
index 2e710ca..1aedf76 100644 (file)
@@ -523,10 +523,7 @@ typedef struct _GDIBSEXTSELCLPRGN
 {
   GDIBATCHHDR gbHdr;
   int fnMode;
-  LONG right;
-  LONG bottom;
-  LONG left;
-  LONG top;
+  RECTL;
 } GDIBSEXTSELCLPRGN, *PGDIBSEXTSELCLPRGN;
 //
 //   Use with GdiBCSelObj, GdiBCDelObj and GdiBCDelRgn.
index a04b7ae..3f02d3d 100644 (file)
@@ -299,13 +299,14 @@ ExFreeToZone(
 #define ExIsResourceAcquired ExIsResourceAcquiredSharedLite
 #define ExReleaseResourceForThread ExReleaseResourceForThreadLite
 
+#ifdef _X86_
+
 typedef enum _INTERLOCKED_RESULT {
   ResultNegative = RESULT_NEGATIVE,
   ResultZero = RESULT_ZERO,
   ResultPositive = RESULT_POSITIVE
 } INTERLOCKED_RESULT;
 
-#ifdef _X86_
 NTKERNELAPI
 INTERLOCKED_RESULT
 FASTCALL
@@ -324,6 +325,7 @@ FASTCALL
 Exfi386InterlockedExchangeUlong(
   IN PULONG  Target,
   IN ULONG  Value);
+
 #endif
 
 $endif (_NTDDK_)
index 59b3843..1be9b65 100644 (file)
@@ -21,7 +21,7 @@ CmCreateRootNode(
    SIZE_T NameSize;
 
    /* Allocate the cell */
-   NameSize = utf16_wcslen(Name) * sizeof(WCHAR);
+   NameSize = strlenW(Name) * sizeof(WCHAR);
    RootCellIndex = HvAllocateCell(Hive,
                                   FIELD_OFFSET(CM_KEY_NODE, Name) + NameSize,
                                   Stable,
index fae0495..e472fd3 100644 (file)
@@ -13,6 +13,7 @@
 #define _CMLIB_DEBUG_ 1
 
 #ifdef CMLIB_HOST
+    #include <wine/unicode.h>
     #include <host/typedefs.h>
     #include <stdio.h>
     #include <string.h>
@@ -198,6 +199,22 @@ typedef struct _CMHIVE
 
 #endif
 
+typedef struct _HV_HIVE_CELL_PAIR
+{
+    PHHIVE Hive;
+    HCELL_INDEX Cell;
+} HV_HIVE_CELL_PAIR, *PHV_HIVE_CELL_PAIR;
+
+#define STATIC_CELL_PAIR_COUNT 4
+typedef struct _HV_TRACK_CELL_REF
+{
+    USHORT Count;
+    USHORT Max;
+    PHV_HIVE_CELL_PAIR CellArray;
+    HV_HIVE_CELL_PAIR StaticArray[STATIC_CELL_PAIR_COUNT];
+    USHORT StaticCount;
+} HV_TRACK_CELL_REF, *PHV_TRACK_CELL_REF;
+
 extern ULONG CmlibTraceLevel;
 
 /*
@@ -272,6 +289,12 @@ HvIsCellDirty(
     IN HCELL_INDEX Cell
 );
 
+BOOLEAN
+CMAPI
+HvHiveWillShrink(
+    IN PHHIVE RegistryHive
+);
+
 BOOLEAN CMAPI
 HvSyncHive(
    PHHIVE RegistryHive);
@@ -288,6 +311,21 @@ CmCreateRootNode(
 VOID CMAPI
 CmPrepareHive(
    PHHIVE RegistryHive);
+   
+   
+BOOLEAN
+CMAPI
+HvTrackCellRef(
+    PHV_TRACK_CELL_REF CellRef,
+    PHHIVE Hive,
+    HCELL_INDEX Cell
+);
+
+VOID
+CMAPI
+HvReleaseFreeCellRefArray(
+    PHV_TRACK_CELL_REF CellRef
+);
 
 /*
  * Private functions.
index 506eef9..ab81a02 100644 (file)
@@ -14,6 +14,8 @@
        <file>hivewrt.c</file>
 </module>
 <module name="cmlibhost" type="hoststaticlibrary">
+       <define name="WINE_UNICODE_API">" "</define>
+       <include base="unicode" />
        <include base="cmlibhost">.</include>
        <define name="__NO_CTYPE_INLINES" />
        <define name="_NTOSKRNL_" />
index 994ca98..8151651 100644 (file)
@@ -113,7 +113,7 @@ HvMarkCellDirty(
        __FUNCTION__, RegistryHive, CellIndex, HoldingLock);
 
    if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != Stable)
-      return FALSE;
+      return TRUE;
 
    CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
    CellLastBlock = ((CellIndex + HV_BLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
@@ -525,3 +525,56 @@ HvFreeCell(
    if (CellType == Stable)
       HvMarkCellDirty(RegistryHive, CellIndex, FALSE);
 }
+
+BOOLEAN
+CMAPI
+HvTrackCellRef(PHV_TRACK_CELL_REF CellRef,
+               PHHIVE Hive,
+               HCELL_INDEX Cell)
+{
+    /* Sanity checks */
+    ASSERT(CellRef);
+    ASSERT(Hive );
+    ASSERT(Cell != HCELL_NIL);
+
+    /* Less than 4? */
+    if (CellRef->StaticCount < STATIC_CELL_PAIR_COUNT)
+    {
+        /* Add reference */
+        CellRef->StaticArray[CellRef->StaticCount].Hive = Hive;
+        CellRef->StaticArray[CellRef->StaticCount].Cell = Cell;
+        CellRef->StaticCount++;
+        return TRUE;
+    }
+    
+    /* FIXME: TODO */
+    DPRINT1("ERROR: Too many references\n");
+    while (TRUE);
+    return FALSE;
+}
+
+VOID
+CMAPI
+HvReleaseFreeCellRefArray(PHV_TRACK_CELL_REF CellRef)
+{
+    ULONG i;
+    ASSERT(CellRef);
+
+    /* Any references? */
+    if (CellRef->StaticCount > 0)
+    { 
+        /* Sanity check */
+        ASSERT(CellRef->StaticCount <= STATIC_CELL_PAIR_COUNT);
+        
+        /* Loop them */
+        for (i = 0; i < CellRef->StaticCount;i++)
+        {
+            /* Release them */
+            HvReleaseCell(CellRef->StaticArray[i].Hive,
+                          CellRef->StaticArray[i].Cell);
+        }
+
+        /* Free again */
+        CellRef->StaticCount = 0;
+    }
+}
\ No newline at end of file
index 5cc20cf..7ecadff 100644 (file)
@@ -265,6 +265,14 @@ HvSyncHive(
    return TRUE;
 }
 
+BOOLEAN
+CMAPI
+HvHiveWillShrink(IN PHHIVE RegistryHive)
+{
+    /* No shrinking yet */
+    return FALSE;
+}
+
 BOOLEAN CMAPI
 HvWriteHive(
    PHHIVE RegistryHive)
index ae02e4a..187c9a5 100644 (file)
@@ -735,16 +735,24 @@ NTSTATUS TCPClose
     Socket = Connection->SocketContext;
     Connection->SocketContext = NULL;
 
-    /* We need to close here otherwise oskit will never indicate
-     * SEL_FIN and we will never fully close the connection
-     */
-    Status = TCPTranslateError( OskitTCPClose( Socket ) );
+    /* Don't try to close again if the other side closed us already */
+    if (Connection->SignalState != SEL_FIN)
+    {
+       /* We need to close here otherwise oskit will never indicate
+        * SEL_FIN and we will never fully close the connection */
+       Status = TCPTranslateError( OskitTCPClose( Socket ) );
 
-    if (!NT_SUCCESS(Status))
+       if (!NT_SUCCESS(Status))
+       {
+           Connection->SocketContext = Socket;
+           UnlockObject(Connection, OldIrql);
+           return Status;
+       }
+    }
+    else
     {
-        Connection->SocketContext = Socket;
-        UnlockObject(Connection, OldIrql);
-        return Status;
+       /* We are already closed by the other end so return success */
+       Status = STATUS_SUCCESS;
     }
 
     if (Connection->AddressFile)
index d29fa5f..aa8d246 100644 (file)
@@ -41,5 +41,10 @@ void* oskit_bufio_create(int len)
 }
 void oskit_bufio_map(void *srcbuf, void**dstbuf, int off, int len)
 {
+#if DBG
+   if (off != 0)
+       panic("oskit_bufio_map: offset is non-zero");
+#endif
+
    *dstbuf = srcbuf;
 }
index a8b2675..0ba0aae 100644 (file)
@@ -360,6 +360,17 @@ MMixerInitializeWaveInfo(
     WaveInfo->DeviceId = MixerData->DeviceId;
     WaveInfo->PinId = PinId;
 
+
+    /* copy device name */
+    if (bWaveIn)
+    {
+        wcscpy(WaveInfo->u.InCaps.szPname, DeviceName);
+    }
+    else
+    {
+        wcscpy(WaveInfo->u.OutCaps.szPname, DeviceName);
+    }
+
     /* FIXME determine manufacturer / product id */
     if (bWaveIn)
     {
@@ -410,6 +421,8 @@ MMixerInitializeWaveInfo(
     MixerContext->Free(MultipleItem);
 
 
+
+
     if (bWaveIn)
     {
         InsertTailList(&MixerList->WaveInList, &WaveInfo->Entry);
index fc40b74..58dafe1 100644 (file)
@@ -18,6 +18,17 @@ SIZE_T utf16_wcslen(PCWSTR str)
     return i;
 }
 
+
+SIZE_T strlenW(PCWSTR str)
+{
+    SIZE_T i;
+
+    for(i = 0; str[i]; i++);
+
+    return i;
+}
+
+
 PWSTR utf16_wcschr(PWSTR str, WCHAR c)
 {
     SIZE_T i;
@@ -30,6 +41,18 @@ PWSTR utf16_wcschr(PWSTR str, WCHAR c)
         return NULL;
 }
 
+PWSTR strchrW(PWSTR str, WCHAR c)
+{
+    SIZE_T i;
+
+    for(i = 0; str[i] && str[i] != c; i++);
+
+    if(str[i])
+        return &str[i];
+    else
+        return NULL;
+}
+
 INT utf16_wcsncmp(PCWSTR string1, PCWSTR string2, size_t count)
 {
     while(count--)
@@ -46,3 +69,20 @@ INT utf16_wcsncmp(PCWSTR string1, PCWSTR string2, size_t count)
 
     return 0;
 }
+
+INT strncmpW(PCWSTR string1, PCWSTR string2, size_t count)
+{
+    while(count--)
+    {
+        if(*string1 != *string2)
+            return 1;
+
+        if(*string1 == 0)
+            return 0;
+
+        string1++;
+        string2++;
+    }
+
+    return 0;
+}
index 42e49d6..fe9cf99 100644 (file)
@@ -37,6 +37,9 @@
        <directory name="lsalib">
                <xi:include href="lsalib/lsalib.rbuild" />
        </directory>
+       <directory name="newinflib">
+               <xi:include href="newinflib/inflib.rbuild" />
+       </directory>
        <directory name="nls">
                <xi:include href="nls/nls.rbuild" />
        </directory>
diff --git a/lib/newinflib/README.txt b/lib/newinflib/README.txt
new file mode 100644 (file)
index 0000000..5e27e2b
--- /dev/null
@@ -0,0 +1,16 @@
+Routines to handle .inf files.
+
+This is the UNICODE-enabled version of inflib. It will be used by usetup and mkhive.
+
+This library is used to share .inf handling code between build tools and
+ReactOS code. Two versions are built, "inflib_host" (for use by build tools)
+and "inflib" (for use by ReactOS code). Both depend on the same core source,
+with a wrapper for the appropriate interface.
+Most of the differences between the host and the ReactOS environment are
+abstracted away in builddep.h. Of particular note is that the host version
+uses Ansi characters while the ReactOS version uses Unicode. So, the core
+source uses TCHARs. builddep.h depends on a preprocessor variable INFLIB_HOST
+which is defined when building the host version (inflib.mak) but not defined
+when building the ReactOS version (inflib.xml).
+The wrappers have "host" or "ros" in their filename. The library interface is
+"infhost.h" for the host version, "infros.h" for the ReactOS version.
diff --git a/lib/newinflib/builddep.h b/lib/newinflib/builddep.h
new file mode 100644 (file)
index 0000000..51b4d48
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * PROJECT:   .inf file parser
+ * LICENSE:   GPL - See COPYING in the top level directory
+ * COPYRIGHT: Copyright 2005 Ge van Geldorp <gvg@reactos.org>
+ */
+
+#ifdef INFLIB_HOST
+
+/* Definitions native to the host on which we're building */
+
+#include <wine/unicode.h>
+#include <host/typedefs.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#define FREE(Area) free(Area)
+#define MALLOC(Size) malloc((size_t)(Size))
+#define ZEROMEMORY(Area, Size) memset((Area), '\0', (size_t)(Size))
+#define MEMCPY(Dest, Src, Size) memcpy((Dest), (Src), (size_t)(Size))
+
+#define STATUS_SUCCESS               0
+#define INF_STATUS_SUCCESS           0
+#define INF_STATUS_NO_MEMORY         ENOMEM
+#define INF_STATUS_INVALID_PARAMETER EINVAL
+#define INF_STATUS_NOT_FOUND         ENOENT
+#define INF_STATUS_BUFFER_OVERFLOW   E2BIG
+#define INF_SUCCESS(x) (0 == (x))
+
+#define STRFMT "%s"
+
+NTSTATUS NTAPI RtlMultiByteToUnicodeN(IN PWCHAR UnicodeString,
+    IN ULONG UnicodeSize, IN PULONG ResultSize, IN PCSTR MbString, IN ULONG MbSize);
+
+BOOLEAN NTAPI RtlIsTextUnicode( PVOID buf, INT len, INT *pf );
+
+
+#define IS_TEXT_UNICODE_ASCII16 1
+#define IS_TEXT_UNICODE_REVERSE_ASCII16 16
+#define IS_TEXT_UNICODE_STATISTICS 2
+#define IS_TEXT_UNICODE_REVERSE_STATISTICS 32
+#define IS_TEXT_UNICODE_CONTROLS 4
+#define IS_TEXT_UNICODE_REVERSE_CONTROLS 64
+#define IS_TEXT_UNICODE_SIGNATURE 8
+#define IS_TEXT_UNICODE_REVERSE_SIGNATURE 128
+#define IS_TEXT_UNICODE_ILLEGAL_CHARS 256
+#define IS_TEXT_UNICODE_ODD_LENGTH 512
+#define IS_TEXT_UNICODE_NULL_BYTES 4096
+#define IS_TEXT_UNICODE_UNICODE_MASK 15
+#define IS_TEXT_UNICODE_REVERSE_MASK 240
+#define IS_TEXT_UNICODE_NOT_UNICODE_MASK 3840
+#define IS_TEXT_UNICODE_NOT_ASCII_MASK 61440
+
+#else /* ! defined(INFLIB_HOST) */
+
+/* ReactOS definitions */
+
+#define UNICODE
+#define _UNICODE
+#define WIN32_NO_STATUS
+#include <windows.h>
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
+
+extern PVOID InfpHeap;
+
+#define FREE(Area) RtlFreeHeap(InfpHeap, 0, (Area))
+#define MALLOC(Size) RtlAllocateHeap(InfpHeap, 0, (Size))
+#define ZEROMEMORY(Area, Size) RtlZeroMemory((Area), (Size))
+#define MEMCPY(Dest, Src, Size) RtlCopyMemory((Dest), (Src), (Size))
+
+#define INF_STATUS_SUCCESS           STATUS_SUCCESS
+#define INF_STATUS_NO_MEMORY         STATUS_NO_MEMORY
+#define INF_STATUS_INVALID_PARAMETER STATUS_INVALID_PARAMETER
+#define INF_STATUS_NOT_FOUND         STATUS_NOT_FOUND
+#define INF_STATUS_BUFFER_OVERFLOW   STATUS_BUFFER_OVERFLOW
+#define INF_SUCCESS(x) (0 <= (x))
+
+#define STRFMT "%S"
+
+#endif /* INFLIB_HOST */
+
+#include <host/wcsfuncs.h>
+
+/* EOF */
diff --git a/lib/newinflib/infcommon.h b/lib/newinflib/infcommon.h
new file mode 100644 (file)
index 0000000..a80f202
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ *             Eric Kohl
+ *             Ge van Geldorp <gvg@reactos.org>
+ */
+
+#pragma once
+
+#define MAX_INF_STRING_LENGTH  512
+
+typedef void *HINF, **PHINF;
+typedef struct _INFCONTEXT *PINFCONTEXT;
+
+/* EOF */
diff --git a/lib/newinflib/infcore.c b/lib/newinflib/infcore.c
new file mode 100644 (file)
index 0000000..7e18735
--- /dev/null
@@ -0,0 +1,832 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ *             Eric Kohl
+ *             Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+
+#define NDEBUG
+#include <debug.h>
+
+#define CONTROL_Z  '\x1a'
+#define MAX_SECTION_NAME_LEN  255
+#define MAX_FIELD_LEN         511  /* larger fields get silently truncated */
+/* actual string limit is MAX_INF_STRING_LENGTH+1 (plus terminating null) under Windows */
+#define MAX_STRING_LEN        (MAX_INF_STRING_LENGTH+1)
+
+
+/* parser definitions */
+
+enum parser_state
+{
+  LINE_START,      /* at beginning of a line */
+  SECTION_NAME,    /* parsing a section name */
+  KEY_NAME,        /* parsing a key name */
+  VALUE_NAME,      /* parsing a value name */
+  EOL_BACKSLASH,   /* backslash at end of line */
+  QUOTES,          /* inside quotes */
+  LEADING_SPACES,  /* leading spaces */
+  TRAILING_SPACES, /* trailing spaces */
+  COMMENT,         /* inside a comment */
+  NB_PARSER_STATES
+};
+
+struct parser
+{
+  const WCHAR       *start;       /* start position of item being parsed */
+  const WCHAR       *end;         /* end of buffer */
+  PINFCACHE         file;         /* file being built */
+  enum parser_state state;        /* current parser state */
+  enum parser_state stack[4];     /* state stack */
+  int               stack_pos;    /* current pos in stack */
+
+  PINFCACHESECTION cur_section;   /* pointer to the section being parsed*/
+  PINFCACHELINE    line;          /* current line */
+  unsigned int     line_pos;      /* current line position in file */
+  INFSTATUS        error;         /* error code */
+  unsigned int     token_len;     /* current token len */
+  WCHAR token[MAX_FIELD_LEN+1];   /* current token */
+};
+
+typedef const WCHAR * (*parser_state_func)( struct parser *parser, const WCHAR *pos );
+
+/* parser state machine functions */
+static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos );
+static const WCHAR *section_name_state( struct parser *parser, const WCHAR *pos );
+static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos );
+static const WCHAR *value_name_state( struct parser *parser, const WCHAR *pos );
+static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos );
+static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos );
+static const WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos );
+static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos );
+static const WCHAR *comment_state( struct parser *parser, const WCHAR *pos );
+
+static const parser_state_func parser_funcs[NB_PARSER_STATES] =
+{
+  line_start_state,      /* LINE_START */
+  section_name_state,    /* SECTION_NAME */
+  key_name_state,        /* KEY_NAME */
+  value_name_state,      /* VALUE_NAME */
+  eol_backslash_state,   /* EOL_BACKSLASH */
+  quotes_state,          /* QUOTES */
+  leading_spaces_state,  /* LEADING_SPACES */
+  trailing_spaces_state, /* TRAILING_SPACES */
+  comment_state          /* COMMENT */
+};
+
+
+/* PRIVATE FUNCTIONS ********************************************************/
+
+static PINFCACHELINE
+InfpFreeLine (PINFCACHELINE Line)
+{
+  PINFCACHELINE Next;
+  PINFCACHEFIELD Field;
+
+  if (Line == NULL)
+    {
+      return NULL;
+    }
+
+  Next = Line->Next;
+  if (Line->Key != NULL)
+    {
+      FREE (Line->Key);
+      Line->Key = NULL;
+    }
+
+  /* Remove data fields */
+  while (Line->FirstField != NULL)
+    {
+      Field = Line->FirstField->Next;
+      FREE (Line->FirstField);
+      Line->FirstField = Field;
+    }
+  Line->LastField = NULL;
+
+  FREE (Line);
+
+  return Next;
+}
+
+
+PINFCACHESECTION
+InfpFreeSection (PINFCACHESECTION Section)
+{
+  PINFCACHESECTION Next;
+
+  if (Section == NULL)
+    {
+      return NULL;
+    }
+
+  /* Release all keys */
+  Next = Section->Next;
+  while (Section->FirstLine != NULL)
+    {
+      Section->FirstLine = InfpFreeLine (Section->FirstLine);
+    }
+  Section->LastLine = NULL;
+
+  FREE (Section);
+
+  return Next;
+}
+
+
+PINFCACHESECTION
+InfpFindSection(PINFCACHE Cache,
+                PCWSTR Name)
+{
+  PINFCACHESECTION Section = NULL;
+
+  if (Cache == NULL || Name == NULL)
+    {
+      return NULL;
+    }
+
+  /* iterate through list of sections */
+  Section = Cache->FirstSection;
+  while (Section != NULL)
+    {
+      if (strcmpiW(Section->Name, Name) == 0)
+        {
+          return Section;
+        }
+
+      /* get the next section*/
+      Section = Section->Next;
+    }
+
+  return NULL;
+}
+
+
+PINFCACHESECTION
+InfpAddSection(PINFCACHE Cache,
+               PCWSTR Name)
+{
+  PINFCACHESECTION Section = NULL;
+  ULONG Size;
+
+  if (Cache == NULL || Name == NULL)
+    {
+      DPRINT("Invalid parameter\n");
+      return NULL;
+    }
+
+  /* Allocate and initialize the new section */
+  Size = (ULONG)FIELD_OFFSET(INFCACHESECTION,
+                             Name[strlenW(Name) + 1]);
+  Section = (PINFCACHESECTION)MALLOC(Size);
+  if (Section == NULL)
+    {
+      DPRINT("MALLOC() failed\n");
+      return NULL;
+    }
+  ZEROMEMORY (Section,
+              Size);
+
+  /* Copy section name */
+  strcpyW(Section->Name, Name);
+
+  /* Append section */
+  if (Cache->FirstSection == NULL)
+    {
+      Cache->FirstSection = Section;
+      Cache->LastSection = Section;
+    }
+  else
+    {
+      Cache->LastSection->Next = Section;
+      Section->Prev = Cache->LastSection;
+      Cache->LastSection = Section;
+    }
+
+  return Section;
+}
+
+
+PINFCACHELINE
+InfpAddLine(PINFCACHESECTION Section)
+{
+  PINFCACHELINE Line;
+
+  if (Section == NULL)
+    {
+      DPRINT("Invalid parameter\n");
+      return NULL;
+    }
+
+  Line = (PINFCACHELINE)MALLOC(sizeof(INFCACHELINE));
+  if (Line == NULL)
+    {
+      DPRINT("MALLOC() failed\n");
+      return NULL;
+    }
+  ZEROMEMORY(Line,
+             sizeof(INFCACHELINE));
+
+  /* Append line */
+  if (Section->FirstLine == NULL)
+    {
+      Section->FirstLine = Line;
+      Section->LastLine = Line;
+    }
+  else
+    {
+      Section->LastLine->Next = Line;
+      Line->Prev = Section->LastLine;
+      Section->LastLine = Line;
+    }
+  Section->LineCount++;
+
+  return Line;
+}
+
+
+PVOID
+InfpAddKeyToLine(PINFCACHELINE Line,
+                 PCWSTR Key)
+{
+  if (Line == NULL)
+    {
+      DPRINT1("Invalid Line\n");
+      return NULL;
+    }
+
+  if (Line->Key != NULL)
+    {
+      DPRINT1("Line already has a key\n");
+      return NULL;
+    }
+
+  Line->Key = (PWCHAR)MALLOC((strlenW(Key) + 1) * sizeof(WCHAR));
+  if (Line->Key == NULL)
+    {
+      DPRINT1("MALLOC() failed\n");
+      return NULL;
+    }
+
+  strcpyW(Line->Key, Key);
+
+  return (PVOID)Line->Key;
+}
+
+
+PVOID
+InfpAddFieldToLine(PINFCACHELINE Line,
+                   PCWSTR Data)
+{
+  PINFCACHEFIELD Field;
+  ULONG Size;
+
+  Size = (ULONG)FIELD_OFFSET(INFCACHEFIELD,
+                             Data[strlenW(Data) + 1]);
+  Field = (PINFCACHEFIELD)MALLOC(Size);
+  if (Field == NULL)
+    {
+      DPRINT1("MALLOC() failed\n");
+      return NULL;
+    }
+  ZEROMEMORY (Field,
+              Size);
+  strcpyW(Field->Data, Data);
+
+  /* Append key */
+  if (Line->FirstField == NULL)
+    {
+      Line->FirstField = Field;
+      Line->LastField = Field;
+    }
+  else
+    {
+      Line->LastField->Next = Field;
+      Field->Prev = Line->LastField;
+      Line->LastField = Field;
+    }
+  Line->FieldCount++;
+
+  return (PVOID)Field;
+}
+
+
+PINFCACHELINE
+InfpFindKeyLine(PINFCACHESECTION Section,
+                PCWSTR Key)
+{
+  PINFCACHELINE Line;
+
+  Line = Section->FirstLine;
+  while (Line != NULL)
+    {
+      if (Line->Key != NULL && strcmpiW(Line->Key, Key) == 0)
+        {
+          return Line;
+        }
+
+      Line = Line->Next;
+    }
+
+  return NULL;
+}
+
+
+/* push the current state on the parser stack */
+__inline static void push_state( struct parser *parser, enum parser_state state )
+{
+//  assert( parser->stack_pos < sizeof(parser->stack)/sizeof(parser->stack[0]) );
+  parser->stack[parser->stack_pos++] = state;
+}
+
+
+/* pop the current state */
+__inline static void pop_state( struct parser *parser )
+{
+//  assert( parser->stack_pos );
+  parser->state = parser->stack[--parser->stack_pos];
+}
+
+
+/* set the parser state and return the previous one */
+__inline static enum parser_state set_state( struct parser *parser, enum parser_state state )
+{
+  enum parser_state ret = parser->state;
+  parser->state = state;
+  return ret;
+}
+
+
+/* check if the pointer points to an end of file */
+__inline static int is_eof( struct parser *parser, const WCHAR *ptr )
+{
+  return (ptr >= parser->end || *ptr == CONTROL_Z || *ptr == 0);
+}
+
+
+/* check if the pointer points to an end of line */
+__inline static int is_eol( struct parser *parser, const WCHAR *ptr )
+{
+  return (ptr >= parser->end ||
+          *ptr == CONTROL_Z ||
+          *ptr == '\n' ||
+          (*ptr == '\r' && *(ptr + 1) == '\n') ||
+          *ptr == 0);
+}
+
+
+/* push data from current token start up to pos into the current token */
+static int push_token( struct parser *parser, const WCHAR *pos )
+{
+  UINT len = (UINT)(pos - parser->start);
+  const WCHAR *src = parser->start;
+  WCHAR *dst = parser->token + parser->token_len;
+
+  if (len > MAX_FIELD_LEN - parser->token_len)
+    len = MAX_FIELD_LEN - parser->token_len;
+
+  parser->token_len += len;
+  for ( ; len > 0; len--, dst++, src++)
+  {
+    if (*src)
+    {
+      *dst = *src;
+    }
+    else
+    {
+      *dst = ' ';
+    }
+  }
+
+  *dst = 0;
+  parser->start = pos;
+
+  return 0;
+}
+
+
+
+/* add a section with the current token as name */
+static PVOID add_section_from_token( struct parser *parser )
+{
+  PINFCACHESECTION Section;
+
+  if (parser->token_len > MAX_SECTION_NAME_LEN)
+    {
+      parser->error = INF_STATUS_SECTION_NAME_TOO_LONG;
+      return NULL;
+    }
+
+  Section = InfpFindSection(parser->file,
+                            parser->token);
+  if (Section == NULL)
+    {
+      /* need to create a new one */
+      Section= InfpAddSection(parser->file,
+                              parser->token);
+      if (Section == NULL)
+        {
+          parser->error = INF_STATUS_NOT_ENOUGH_MEMORY;
+          return NULL;
+        }
+    }
+
+  parser->token_len = 0;
+  parser->cur_section = Section;
+
+  return (PVOID)Section;
+}
+
+
+/* add a field containing the current token to the current line */
+static struct field *add_field_from_token( struct parser *parser, int is_key )
+{
+  PVOID field;
+
+  if (!parser->line)  /* need to start a new line */
+    {
+      if (parser->cur_section == NULL)  /* got a line before the first section */
+        {
+          parser->error = INF_STATUS_WRONG_INF_STYLE;
+          return NULL;
+        }
+
+      parser->line = InfpAddLine(parser->cur_section);
+      if (parser->line == NULL)
+        goto error;
+    }
+  else
+    {
+//      assert(!is_key);
+    }
+
+  if (is_key)
+    {
+      field = InfpAddKeyToLine(parser->line, parser->token);
+    }
+  else
+    {
+      field = InfpAddFieldToLine(parser->line, parser->token);
+    }
+
+  if (field != NULL)
+    {
+      parser->token_len = 0;
+      return field;
+    }
+
+error:
+  parser->error = INF_STATUS_NOT_ENOUGH_MEMORY;
+  return NULL;
+}
+
+
+/* close the current line and prepare for parsing a new one */
+static void close_current_line( struct parser *parser )
+{
+  parser->line = NULL;
+}
+
+
+
+/* handler for parser LINE_START state */
+static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos )
+{
+  const WCHAR *p;
+
+  for (p = pos; !is_eof( parser, p ); p++)
+    {
+      switch(*p)
+        {
+          case '\r':
+            continue;
+
+          case '\n':
+            parser->line_pos++;
+            close_current_line( parser );
+            break;
+
+          case ';':
+            push_state( parser, LINE_START );
+            set_state( parser, COMMENT );
+            return p + 1;
+
+          case '[':
+            parser->start = p + 1;
+            set_state( parser, SECTION_NAME );
+            return p + 1;
+
+          default:
+            if (!isspaceW(*p))
+              {
+                parser->start = p;
+                set_state( parser, KEY_NAME );
+                return p;
+              }
+            break;
+        }
+    }
+  close_current_line( parser );
+  return NULL;
+}
+
+
+/* handler for parser SECTION_NAME state */
+static const WCHAR *section_name_state( struct parser *parser, const WCHAR *pos )
+{
+  const WCHAR *p;
+
+  for (p = pos; !is_eol( parser, p ); p++)
+    {
+      if (*p == ']')
+        {
+          push_token( parser, p );
+          if (add_section_from_token( parser ) == NULL)
+            return NULL;
+          push_state( parser, LINE_START );
+          set_state( parser, COMMENT );  /* ignore everything else on the line */
+          return p + 1;
+        }
+    }
+  parser->error = INF_STATUS_BAD_SECTION_NAME_LINE; /* unfinished section name */
+  return NULL;
+}
+
+
+/* handler for parser KEY_NAME state */
+static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos )
+{
+    const WCHAR *p, *token_end = parser->start;
+
+    for (p = pos; !is_eol( parser, p ); p++)
+    {
+        if (*p == ',') break;
+        switch(*p)
+        {
+
+         case '=':
+            push_token( parser, token_end );
+            if (!add_field_from_token( parser, 1 )) return NULL;
+            parser->start = p + 1;
+            push_state( parser, VALUE_NAME );
+            set_state( parser, LEADING_SPACES );
+            return p + 1;
+        case ';':
+            push_token( parser, token_end );
+            if (!add_field_from_token( parser, 0 )) return NULL;
+            push_state( parser, LINE_START );
+            set_state( parser, COMMENT );
+            return p + 1;
+        case '"':
+            push_token( parser, token_end );
+            parser->start = p + 1;
+            push_state( parser, KEY_NAME );
+            set_state( parser, QUOTES );
+            return p + 1;
+        case '\\':
+            push_token( parser, token_end );
+            parser->start = p;
+            push_state( parser, KEY_NAME );
+            set_state( parser, EOL_BACKSLASH );
+            return p;
+        default:
+            if (!isspaceW(*p)) token_end = p + 1;
+            else
+            {
+                push_token( parser, p );
+                push_state( parser, KEY_NAME );
+                set_state( parser, TRAILING_SPACES );
+                return p;
+            }
+            break;
+        }
+    }
+    push_token( parser, token_end );
+    set_state( parser, VALUE_NAME );
+    return p;
+}
+
+
+/* handler for parser VALUE_NAME state */
+static const WCHAR *value_name_state( struct parser *parser, const WCHAR *pos )
+{
+    const WCHAR *p, *token_end = parser->start;
+
+    for (p = pos; !is_eol( parser, p ); p++)
+    {
+        switch(*p)
+        {
+        case ';':
+            push_token( parser, token_end );
+            if (!add_field_from_token( parser, 0 )) return NULL;
+            push_state( parser, LINE_START );
+            set_state( parser, COMMENT );
+            return p + 1;
+        case ',':
+            push_token( parser, token_end );
+            if (!add_field_from_token( parser, 0 )) return NULL;
+            parser->start = p + 1;
+            push_state( parser, VALUE_NAME );
+            set_state( parser, LEADING_SPACES );
+            return p + 1;
+        case '"':
+            push_token( parser, token_end );
+            parser->start = p + 1;
+            push_state( parser, VALUE_NAME );
+            set_state( parser, QUOTES );
+            return p + 1;
+        case '\\':
+            push_token( parser, token_end );
+            parser->start = p;
+            push_state( parser, VALUE_NAME );
+            set_state( parser, EOL_BACKSLASH );
+            return p;
+        default:
+            if (!isspaceW(*p)) token_end = p + 1;
+            else
+            {
+                push_token( parser, p );
+                push_state( parser, VALUE_NAME );
+                set_state( parser, TRAILING_SPACES );
+                return p;
+            }
+            break;
+        }
+    }
+    push_token( parser, token_end );
+    if (!add_field_from_token( parser, 0 )) return NULL;
+    set_state( parser, LINE_START );
+    return p;
+}
+
+
+/* handler for parser EOL_BACKSLASH state */
+static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos )
+{
+  const WCHAR *p;
+
+  for (p = pos; !is_eof( parser, p ); p++)
+    {
+      switch(*p)
+        {
+          case '\r':
+            continue;
+
+          case '\n':
+            parser->line_pos++;
+            parser->start = p + 1;
+            set_state( parser, LEADING_SPACES );
+            return p + 1;
+
+          case '\\':
+            continue;
+
+          case ';':
+            push_state( parser, EOL_BACKSLASH );
+            set_state( parser, COMMENT );
+            return p + 1;
+
+          default:
+            if (isspaceW(*p))
+              continue;
+            push_token( parser, p );
+            pop_state( parser );
+            return p;
+        }
+    }
+  parser->start = p;
+  pop_state( parser );
+
+  return p;
+}
+
+
+/* handler for parser QUOTES state */
+static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos )
+{
+  const WCHAR *p, *token_end = parser->start;
+
+  for (p = pos; !is_eol( parser, p ); p++)
+    {
+      if (*p == '"')
+        {
+          if (p+1 < parser->end && p[1] == '"')  /* double quotes */
+            {
+              push_token( parser, p + 1 );
+              parser->start = token_end = p + 2;
+              p++;
+            }
+          else  /* end of quotes */
+            {
+              push_token( parser, p );
+              parser->start = p + 1;
+              pop_state( parser );
+              return p + 1;
+            }
+        }
+    }
+  push_token( parser, p );
+  pop_state( parser );
+  return p;
+}
+
+
+/* handler for parser LEADING_SPACES state */
+static const WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos )
+{
+  const WCHAR *p;
+
+  for (p = pos; !is_eol( parser, p ); p++)
+    {
+      if (*p == '\\')
+        {
+          parser->start = p;
+          set_state( parser, EOL_BACKSLASH );
+          return p;
+        }
+      if (!isspaceW(*p))
+        break;
+    }
+  parser->start = p;
+  pop_state( parser );
+  return p;
+}
+
+
+/* handler for parser TRAILING_SPACES state */
+static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos )
+{
+  const WCHAR *p;
+
+  for (p = pos; !is_eol( parser, p ); p++)
+    {
+      if (*p == '\\')
+        {
+          set_state( parser, EOL_BACKSLASH );
+          return p;
+        }
+      if (!isspaceW(*p))
+        break;
+    }
+  pop_state( parser );
+  return p;
+}
+
+
+/* handler for parser COMMENT state */
+static const WCHAR *comment_state( struct parser *parser, const WCHAR *pos )
+{
+  const WCHAR *p = pos;
+
+  while (!is_eol( parser, p ))
+     p++;
+  pop_state( parser );
+  return p;
+}
+
+
+/* parse a complete buffer */
+INFSTATUS
+InfpParseBuffer (PINFCACHE file,
+                 const WCHAR *buffer,
+                 const WCHAR *end,
+                 PULONG error_line)
+{
+  struct parser parser;
+  const WCHAR *pos = buffer;
+
+  parser.start       = buffer;
+  parser.end         = end;
+  parser.file        = file;
+  parser.line        = NULL;
+  parser.state       = LINE_START;
+  parser.stack_pos   = 0;
+  parser.cur_section = NULL;
+  parser.line_pos    = 1;
+  parser.error       = 0;
+  parser.token_len   = 0;
+
+  /* parser main loop */
+  while (pos)
+    pos = (parser_funcs[parser.state])(&parser, pos);
+
+  if (parser.error)
+    {
+      if (error_line)
+        *error_line = parser.line_pos;
+      return parser.error;
+    }
+
+  /* find the [strings] section */
+  file->StringsSection = InfpFindSection(file,
+                                         L"Strings");
+
+  return INF_STATUS_SUCCESS;
+}
+
+/* EOF */
diff --git a/lib/newinflib/infget.c b/lib/newinflib/infget.c
new file mode 100644 (file)
index 0000000..e2b360a
--- /dev/null
@@ -0,0 +1,668 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ *             Eric Kohl
+ *             Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+
+#define NDEBUG
+#include <debug.h>
+
+static unsigned int
+InfpSubstituteString(PINFCACHE Inf,
+                     const WCHAR *text,
+                     WCHAR *buffer,
+                     unsigned int size);
+
+/* retrieve the string substitution for a given string, or NULL if not found */
+/* if found, len is set to the substitution length */
+static PCWSTR
+InfpGetSubstitutionString(PINFCACHE Inf,
+                          PCWSTR str,
+                          unsigned int *len,
+                          BOOL no_trailing_slash)
+{
+    static const WCHAR percent = '%';
+
+    INFSTATUS Status = INF_STATUS_NOT_FOUND;
+    PINFCONTEXT Context = NULL;
+    PWCHAR Data = NULL;
+    WCHAR ValueName[MAX_INF_STRING_LENGTH +1];
+    WCHAR StringLangId[13];
+
+    if (!*len)  /* empty string (%%) is replaced by single percent */
+    {
+        *len = 1;
+        return &percent;
+    }
+
+    memcpy(ValueName, str, *len * sizeof(WCHAR));
+    ValueName[*len] = 0;
+
+    DPRINT("Value name: %S\n", ValueName);
+
+    if (Inf->LanguageId != 0)
+    {
+        swprintf(StringLangId,
+                 L"Strings.%04hx",
+                 Inf->LanguageId);
+
+        Status = InfpFindFirstLine(Inf,
+                                   StringLangId,
+                                   ValueName,
+                                   &Context);
+        if (Status != INF_STATUS_SUCCESS)
+        {
+            swprintf(StringLangId,
+                     L"Strings.%04hx",
+                     MAKELANGID(PRIMARYLANGID(Inf->LanguageId), SUBLANG_NEUTRAL));
+
+            Status = InfpFindFirstLine(Inf,
+                                       StringLangId,
+                                       ValueName,
+                                       &Context);
+            if (Status != INF_STATUS_SUCCESS)
+            {
+                Status = InfpFindFirstLine(Inf,
+                                           L"Strings",
+                                           ValueName,
+                                           &Context);
+            }
+        }
+    }
+    else
+    {
+        Status = InfpFindFirstLine(Inf,
+                                   L"Strings",
+                                   ValueName,
+                                   &Context);
+    }
+
+    if (Status != INF_STATUS_SUCCESS || Context == NULL)
+        return NULL;
+
+    Status = InfpGetData(Context,
+                         NULL,
+                         &Data);
+
+    InfpFreeContext(Context);
+
+    if (Status == STATUS_SUCCESS)
+    {
+        *len = strlenW(Data);
+        DPRINT("Substitute: %S  Length: %ul\n", Data, *len);
+        return Data;
+    }
+
+    return NULL;
+}
+
+
+/* do string substitutions on the specified text */
+/* the buffer is assumed to be large enough */
+/* returns necessary length not including terminating null */
+static unsigned int
+InfpSubstituteString(PINFCACHE Inf,
+                     PCWSTR text,
+                     PWSTR buffer,
+                     unsigned int size)
+{
+    const WCHAR *start, *subst, *p;
+    unsigned int len, total = 0;
+    int inside = 0;
+
+    if (!buffer) size = MAX_INF_STRING_LENGTH + 1;
+    for (p = start = text; *p; p++)
+    {
+        if (*p != '%') continue;
+        inside = !inside;
+        if (inside)  /* start of a %xx% string */
+        {
+            len = (unsigned int)(p - start);
+            if (len > size - 1) len = size - 1;
+            if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );
+            total += len;
+            size -= len;
+            start = p;
+        }
+        else /* end of the %xx% string, find substitution */
+        {
+            len = (unsigned int)(p - start - 1);
+            subst = InfpGetSubstitutionString( Inf, start + 1, &len, p[1] == '\\' );
+            if (!subst)
+            {
+                subst = start;
+                len = (unsigned int)(p - start + 1);
+            }
+            if (len > size - 1) len = size - 1;
+            if (buffer) memcpy( buffer + total, subst, len * sizeof(WCHAR) );
+            total += len;
+            size -= len;
+            start = p + 1;
+        }
+    }
+
+    if (start != p) /* unfinished string, copy it */
+    {
+        len = (unsigned int)(p - start);
+        if (len > size - 1) len = size - 1;
+        if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );
+        total += len;
+    }
+    if (buffer && size) buffer[total] = 0;
+    return total;
+}
+
+
+INFSTATUS
+InfpFindFirstLine(PINFCACHE Cache,
+                  PCWSTR Section,
+                  PCWSTR Key,
+                  PINFCONTEXT *Context)
+{
+  PINFCACHESECTION CacheSection;
+  PINFCACHELINE CacheLine;
+
+  if (Cache == NULL || Section == NULL || Context == NULL)
+    {
+      DPRINT1("Invalid parameter\n");
+      return INF_STATUS_INVALID_PARAMETER;
+    }
+
+  CacheSection = InfpFindSection(Cache, Section);
+  if (NULL == CacheSection)
+    {
+      DPRINT("Section not found\n");
+      return INF_STATUS_NOT_FOUND;
+    }
+
+  if (Key != NULL)
+    {
+      CacheLine = InfpFindKeyLine(CacheSection, Key);
+    }
+  else
+    {
+      CacheLine = CacheSection->FirstLine;
+    }
+
+  if (NULL == CacheLine)
+    {
+      DPRINT("Key not found\n");
+      return INF_STATUS_NOT_FOUND;
+    }
+
+  *Context = MALLOC(sizeof(INFCONTEXT));
+  if (NULL == *Context)
+    {
+      DPRINT1("MALLOC() failed\n");
+      return INF_STATUS_NO_MEMORY;
+    }
+  (*Context)->Inf = (PVOID)Cache;
+  (*Context)->Section = (PVOID)CacheSection;
+  (*Context)->Line = (PVOID)CacheLine;
+
+  return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpFindNextLine(PINFCONTEXT ContextIn,
+                 PINFCONTEXT ContextOut)
+{
+  PINFCACHELINE CacheLine;
+
+  if (ContextIn == NULL || ContextOut == NULL)
+    return INF_STATUS_INVALID_PARAMETER;
+
+  if (ContextIn->Line == NULL)
+    return INF_STATUS_INVALID_PARAMETER;
+
+  CacheLine = (PINFCACHELINE)ContextIn->Line;
+  if (CacheLine->Next == NULL)
+    return INF_STATUS_NOT_FOUND;
+
+  if (ContextIn != ContextOut)
+    {
+      ContextOut->Inf = ContextIn->Inf;
+      ContextOut->Section = ContextIn->Section;
+    }
+  ContextOut->Line = (PVOID)(CacheLine->Next);
+
+  return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpFindFirstMatchLine(PINFCONTEXT ContextIn,
+                       PCWSTR Key,
+                       PINFCONTEXT ContextOut)
+{
+  PINFCACHELINE CacheLine;
+
+  if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0)
+    return INF_STATUS_INVALID_PARAMETER;
+
+  if (ContextIn->Inf == NULL || ContextIn->Section == NULL)
+    return INF_STATUS_INVALID_PARAMETER;
+
+  CacheLine = ((PINFCACHESECTION)(ContextIn->Section))->FirstLine;
+  while (CacheLine != NULL)
+    {
+      if (CacheLine->Key != NULL && strcmpiW (CacheLine->Key, Key) == 0)
+        {
+
+          if (ContextIn != ContextOut)
+            {
+              ContextOut->Inf = ContextIn->Inf;
+              ContextOut->Section = ContextIn->Section;
+            }
+          ContextOut->Line = (PVOID)CacheLine;
+
+          return INF_STATUS_SUCCESS;
+        }
+
+      CacheLine = CacheLine->Next;
+    }
+
+  return INF_STATUS_NOT_FOUND;
+}
+
+
+INFSTATUS
+InfpFindNextMatchLine(PINFCONTEXT ContextIn,
+                      PCWSTR Key,
+                      PINFCONTEXT ContextOut)
+{
+  PINFCACHELINE CacheLine;
+
+  if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0)
+    return INF_STATUS_INVALID_PARAMETER;
+
+  if (ContextIn->Inf == NULL || ContextIn->Section == NULL || ContextIn->Line == NULL)
+    return INF_STATUS_INVALID_PARAMETER;
+
+  CacheLine = (PINFCACHELINE)ContextIn->Line;
+  while (CacheLine != NULL)
+    {
+      if (CacheLine->Key != NULL && strcmpiW (CacheLine->Key, Key) == 0)
+        {
+
+          if (ContextIn != ContextOut)
+            {
+              ContextOut->Inf = ContextIn->Inf;
+              ContextOut->Section = ContextIn->Section;
+            }
+          ContextOut->Line = (PVOID)CacheLine;
+
+          return INF_STATUS_SUCCESS;
+        }
+
+      CacheLine = CacheLine->Next;
+    }
+
+  return INF_STATUS_NOT_FOUND;
+}
+
+
+LONG
+InfpGetLineCount(HINF InfHandle,
+                 PCWSTR Section)
+{
+  PINFCACHE Cache;
+  PINFCACHESECTION CacheSection;
+
+  if (InfHandle == NULL || Section == NULL)
+    {
+      DPRINT("Invalid parameter\n");
+      return -1;
+    }
+
+  Cache = (PINFCACHE)InfHandle;
+
+  /* Iterate through list of sections */
+  CacheSection = Cache->FirstSection;
+  while (CacheSection != NULL)
+    {
+      /* Are the section names the same? */
+      if (strcmpiW(CacheSection->Name, Section) == 0)
+        {
+          return CacheSection->LineCount;
+        }
+
+      /* Get the next section */
+      CacheSection = CacheSection->Next;
+    }
+
+  DPRINT("Section not found\n");
+
+  return -1;
+}
+
+
+/* InfpGetLineText */
+
+
+LONG
+InfpGetFieldCount(PINFCONTEXT Context)
+{
+  if (Context == NULL || Context->Line == NULL)
+    return 0;
+
+  return ((PINFCACHELINE)Context->Line)->FieldCount;
+}
+
+
+INFSTATUS
+InfpGetBinaryField(PINFCONTEXT Context,
+                   ULONG FieldIndex,
+                   PUCHAR ReturnBuffer,
+                   ULONG ReturnBufferSize,
+                   PULONG RequiredSize)
+{
+  PINFCACHELINE CacheLine;
+  PINFCACHEFIELD CacheField;
+  ULONG Index;
+  ULONG Size;
+  PUCHAR Ptr;
+
+  if (Context == NULL || Context->Line == NULL || FieldIndex == 0)
+    {
+      DPRINT("Invalid parameter\n");
+      return INF_STATUS_INVALID_PARAMETER;
+    }
+
+  if (RequiredSize != NULL)
+    *RequiredSize = 0;
+
+  CacheLine = (PINFCACHELINE)Context->Line;
+
+  if (FieldIndex > (ULONG)CacheLine->FieldCount)
+    return INF_STATUS_NOT_FOUND;
+
+  CacheField = CacheLine->FirstField;
+  for (Index = 1; Index < FieldIndex; Index++)
+    CacheField = CacheField->Next;
+
+  Size = (ULONG)CacheLine->FieldCount - FieldIndex + 1;
+
+  if (RequiredSize != NULL)
+    *RequiredSize = Size;
+
+  if (ReturnBuffer != NULL)
+    {
+      if (ReturnBufferSize < Size)
+        return INF_STATUS_BUFFER_OVERFLOW;
+
+      /* Copy binary data */
+      Ptr = ReturnBuffer;
+      while (CacheField != NULL)
+        {
+          *Ptr = (UCHAR)strtoulW(CacheField->Data, NULL, 16);
+
+          Ptr++;
+          CacheField = CacheField->Next;
+        }
+    }
+
+  return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpGetIntField(PINFCONTEXT Context,
+                ULONG FieldIndex,
+                PLONG IntegerValue)
+{
+  PINFCACHELINE CacheLine;
+  PINFCACHEFIELD CacheField;
+  ULONG Index;
+  PWCHAR Ptr;
+
+  if (Context == NULL || Context->Line == NULL || IntegerValue == NULL)
+    {
+      DPRINT("Invalid parameter\n");
+      return INF_STATUS_INVALID_PARAMETER;
+    }
+
+  CacheLine = (PINFCACHELINE)Context->Line;
+
+  if (FieldIndex > (ULONG)CacheLine->FieldCount)
+    {
+      DPRINT("Invalid parameter\n");
+      return INF_STATUS_INVALID_PARAMETER;
+    }
+
+  if (FieldIndex == 0)
+    {
+      Ptr = CacheLine->Key;
+    }
+  else
+    {
+      CacheField = CacheLine->FirstField;
+      for (Index = 1; Index < FieldIndex; Index++)
+        CacheField = CacheField->Next;
+
+      Ptr = CacheField->Data;
+    }
+
+  *IntegerValue = (LONG)strtolW(Ptr, NULL, 0);
+
+  return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpGetMultiSzField(PINFCONTEXT Context,
+                    ULONG FieldIndex,
+                    PWSTR ReturnBuffer,
+                    ULONG ReturnBufferSize,
+                    PULONG RequiredSize)
+{
+  PINFCACHELINE CacheLine;
+  PINFCACHEFIELD CacheField;
+  PINFCACHEFIELD FieldPtr;
+  ULONG Index;
+  ULONG Size;
+  PWCHAR Ptr;
+
+  if (Context == NULL || Context->Line == NULL || FieldIndex == 0)
+    {
+      DPRINT("Invalid parameter\n");
+      return INF_STATUS_INVALID_PARAMETER;
+    }
+
+  if (RequiredSize != NULL)
+    *RequiredSize = 0;
+
+  CacheLine = (PINFCACHELINE)Context->Line;
+
+  if (FieldIndex > (ULONG)CacheLine->FieldCount)
+    return INF_STATUS_INVALID_PARAMETER;
+
+  CacheField = CacheLine->FirstField;
+  for (Index = 1; Index < FieldIndex; Index++)
+    CacheField = CacheField->Next;
+
+  /* Calculate the required buffer size */
+  FieldPtr = CacheField;
+  Size = 0;
+  while (FieldPtr != NULL)
+    {
+      Size += ((ULONG)strlenW(FieldPtr->Data) + 1);
+      FieldPtr = FieldPtr->Next;
+    }
+  Size++;
+
+  if (RequiredSize != NULL)
+    *RequiredSize = Size;
+
+  if (ReturnBuffer != NULL)
+    {
+      if (ReturnBufferSize < Size)
+        return INF_STATUS_BUFFER_OVERFLOW;
+
+      /* Copy multi-sz string */
+      Ptr = ReturnBuffer;
+      FieldPtr = CacheField;
+      while (FieldPtr != NULL)
+        {
+          Size = (ULONG)strlenW(FieldPtr->Data) + 1;
+
+          strcpyW(Ptr, FieldPtr->Data);
+
+          Ptr = Ptr + Size;
+          FieldPtr = FieldPtr->Next;
+        }
+      *Ptr = 0;
+    }
+
+  return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpGetStringField(PINFCONTEXT Context,
+                   ULONG FieldIndex,
+                   PWSTR ReturnBuffer,
+                   ULONG ReturnBufferSize,
+                   PULONG RequiredSize)
+{
+  PINFCACHELINE CacheLine;
+  PINFCACHEFIELD CacheField;
+  ULONG Index;
+  PWCHAR Ptr;
+  ULONG Size;
+
+  if (Context == NULL || Context->Line == NULL || FieldIndex == 0)
+    {
+      DPRINT("Invalid parameter\n");
+      return INF_STATUS_INVALID_PARAMETER;
+    }
+
+  if (RequiredSize != NULL)
+    *RequiredSize = 0;
+
+  CacheLine = (PINFCACHELINE)Context->Line;
+
+  if (FieldIndex > (ULONG)CacheLine->FieldCount)
+    return INF_STATUS_INVALID_PARAMETER;
+
+  if (FieldIndex == 0)
+    {
+      Ptr = CacheLine->Key;
+    }
+  else
+    {
+      CacheField = CacheLine->FirstField;
+      for (Index = 1; Index < FieldIndex; Index++)
+        CacheField = CacheField->Next;
+
+      Ptr = CacheField->Data;
+    }
+
+//  Size = (ULONG)strlenW(Ptr) + 1;
+  Size = InfpSubstituteString(Context->Inf,
+                              Ptr,
+                              NULL,
+                              0);
+
+  if (RequiredSize != NULL)
+    *RequiredSize = Size + 1;
+
+  if (ReturnBuffer != NULL)
+    {
+      if (ReturnBufferSize <= Size)
+        return INF_STATUS_BUFFER_OVERFLOW;
+
+//      strcpyW(ReturnBuffer, Ptr);
+      InfpSubstituteString(Context->Inf,
+                           Ptr,
+                           ReturnBuffer,
+                           ReturnBufferSize);
+    }
+
+  return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpGetData(PINFCONTEXT Context,
+            PWCHAR *Key,
+            PWCHAR *Data)
+{
+  PINFCACHELINE CacheKey;
+
+  if (Context == NULL || Context->Line == NULL || Data == NULL)
+    {
+      DPRINT("Invalid parameter\n");
+      return INF_STATUS_INVALID_PARAMETER;
+    }
+
+  CacheKey = (PINFCACHELINE)Context->Line;
+  if (Key != NULL)
+    *Key = CacheKey->Key;
+
+  if (Data != NULL)
+    {
+      if (CacheKey->FirstField == NULL)
+        {
+          *Data = NULL;
+        }
+      else
+        {
+          *Data = CacheKey->FirstField->Data;
+        }
+    }
+
+  return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpGetDataField(PINFCONTEXT Context,
+                 ULONG FieldIndex,
+                 PWCHAR *Data)
+{
+  PINFCACHELINE CacheLine;
+  PINFCACHEFIELD CacheField;
+  ULONG Index;
+
+  if (Context == NULL || Context->Line == NULL || Data == NULL)
+    {
+      DPRINT("Invalid parameter\n");
+      return INF_STATUS_INVALID_PARAMETER;
+    }
+
+  CacheLine = (PINFCACHELINE)Context->Line;
+
+  if (FieldIndex > (ULONG)CacheLine->FieldCount)
+    return INF_STATUS_INVALID_PARAMETER;
+
+  if (FieldIndex == 0)
+    {
+      *Data = CacheLine->Key;
+    }
+  else
+    {
+      CacheField = CacheLine->FirstField;
+      for (Index = 1; Index < FieldIndex; Index++)
+        CacheField = CacheField->Next;
+
+      *Data = CacheField->Data;
+    }
+
+  return INF_STATUS_SUCCESS;
+}
+
+VOID
+InfpFreeContext(PINFCONTEXT Context)
+{
+  FREE(Context);
+}
+
+/* EOF */
diff --git a/lib/newinflib/infhost.h b/lib/newinflib/infhost.h
new file mode 100644 (file)
index 0000000..b1dfaaf
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ *             Eric Kohl
+ *             Ge van Geldorp <gvg@reactos.org>
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "infcommon.h"
+
+extern int InfHostOpenBufferedFile(PHINF InfHandle,
+                                   void *Buffer,
+                                   ULONG BufferSize,
+                                   LANGID LanguageId,
+                                   ULONG *ErrorLine);
+extern int InfHostOpenFile(PHINF InfHandle,
+                           const CHAR *FileName,
+                           LANGID LanguageId,
+                           ULONG *ErrorLine);
+extern int InfHostWriteFile(HINF InfHandle,
+                            const CHAR *FileName,
+                            const CHAR *HeaderComment);
+extern void InfHostCloseFile(HINF InfHandle);
+extern int InfHostFindFirstLine(HINF InfHandle,
+                                const WCHAR *Section,
+                                const WCHAR *Key,
+                                PINFCONTEXT *Context);
+extern int InfHostFindNextLine(PINFCONTEXT ContextIn,
+                               PINFCONTEXT ContextOut);
+extern int InfHostFindFirstMatchLine(PINFCONTEXT ContextIn,
+                                     const WCHAR *Key,
+                                     PINFCONTEXT ContextOut);
+extern int InfHostFindNextMatchLine(PINFCONTEXT ContextIn,
+                                    const WCHAR *Key,
+                                    PINFCONTEXT ContextOut);
+extern LONG InfHostGetLineCount(HINF InfHandle,
+                                const WCHAR *Section);
+extern LONG InfHostGetFieldCount(PINFCONTEXT Context);
+extern int InfHostGetBinaryField(PINFCONTEXT Context,
+                                 ULONG FieldIndex,
+                                 UCHAR *ReturnBuffer,
+                                 ULONG ReturnBufferSize,
+                                 ULONG *RequiredSize);
+extern int InfHostGetIntField(PINFCONTEXT Context,
+                              ULONG FieldIndex,
+                              ULONG *IntegerValue);
+extern int InfHostGetMultiSzField(PINFCONTEXT Context,
+                                  ULONG FieldIndex,
+                                  WCHAR *ReturnBuffer,
+                                  ULONG ReturnBufferSize,
+                                  ULONG *RequiredSize);
+extern int InfHostGetStringField(PINFCONTEXT Context,
+                                 ULONG FieldIndex,
+                                 WCHAR *ReturnBuffer,
+                                 ULONG ReturnBufferSize,
+                                 ULONG *RequiredSize);
+extern int InfHostGetData(PINFCONTEXT Context,
+                          WCHAR **Key,
+                          WCHAR **Data);
+extern int InfHostGetDataField(PINFCONTEXT Context,
+                               ULONG FieldIndex,
+                               WCHAR **Data);
+extern int InfHostFindOrAddSection(HINF InfHandle,
+                                   const WCHAR *Section,
+                                   PINFCONTEXT *Context);
+extern int InfHostAddLine(PINFCONTEXT Context, const WCHAR *Key);
+extern int InfHostAddField(PINFCONTEXT Context, const WCHAR *Data);
+extern void InfHostFreeContext(PINFCONTEXT Context);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/* EOF */
diff --git a/lib/newinflib/infhostgen.c b/lib/newinflib/infhostgen.c
new file mode 100644 (file)
index 0000000..e6269ff
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ *             Eric Kohl
+ *             Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+#include "infhost.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* PUBLIC FUNCTIONS *********************************************************/
+
+int
+InfHostOpenBufferedFile(PHINF InfHandle,
+                        void *Buffer,
+                        ULONG BufferSize,
+                        LANGID LanguageId,
+                        ULONG *ErrorLine)
+{
+  INFSTATUS Status;
+  PINFCACHE Cache;
+  WCHAR *FileBuffer;
+  ULONG FileBufferSize;
+
+  *InfHandle = NULL;
+  *ErrorLine = (ULONG)-1;
+
+  /* Allocate file buffer */
+  FileBufferSize = BufferSize + 2;
+  FileBuffer = MALLOC(FileBufferSize);
+  if (FileBuffer == NULL)
+    {
+      DPRINT1("MALLOC() failed\n");
+      return(INF_STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+  MEMCPY(FileBuffer, Buffer, BufferSize);
+
+  /* Append string terminator */
+  FileBuffer[BufferSize] = 0;
+  FileBuffer[BufferSize + 1] = 0;
+
+  /* Allocate infcache header */
+  Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
+  if (Cache == NULL)
+    {
+      DPRINT1("MALLOC() failed\n");
+      FREE(FileBuffer);
+      return(INF_STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+  /* Initialize inicache header */
+  ZEROMEMORY(Cache,
+             sizeof(INFCACHE));
+
+    Cache->LanguageId = LanguageId;
+
+  /* Parse the inf buffer */
+    if (!RtlIsTextUnicode(FileBuffer, (INT)FileBufferSize, NULL))
+    {
+//        static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
+        WCHAR *new_buff;
+//        UINT codepage = CP_ACP;
+        UINT offset = 0;
+
+//        if (BufferSize > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
+//        {
+//            codepage = CP_UTF8;
+//            offset = sizeof(utf8_bom);
+//        }
+
+        new_buff = MALLOC(FileBufferSize * sizeof(WCHAR));
+        if (new_buff != NULL)
+        {
+            ULONG len;
+            Status = RtlMultiByteToUnicodeN(new_buff,
+                                            FileBufferSize * sizeof(WCHAR),
+                                            &len,
+                                            (char *)FileBuffer + offset,
+                                            FileBufferSize - offset);
+
+            Status = InfpParseBuffer(Cache,
+                                     new_buff,
+                                     new_buff + len / sizeof(WCHAR),
+                                     ErrorLine);
+            FREE(new_buff);
+        }
+        else
+            Status = INF_STATUS_INSUFFICIENT_RESOURCES;
+    }
+    else
+    {
+        WCHAR *new_buff = (WCHAR *)FileBuffer;
+        /* UCS-16 files should start with the Unicode BOM; we should skip it */
+        if (*new_buff == 0xfeff)
+        {
+            new_buff++;
+            FileBufferSize -= sizeof(WCHAR);
+        }
+        Status = InfpParseBuffer(Cache,
+                                 new_buff,
+                                 (WCHAR*)((char*)new_buff + FileBufferSize),
+                                 ErrorLine);
+    }
+
+  if (!INF_SUCCESS(Status))
+    {
+      FREE(Cache);
+      Cache = NULL;
+    }
+
+  /* Free file buffer */
+  FREE(FileBuffer);
+
+  *InfHandle = (HINF)Cache;
+
+  return INF_SUCCESS(Status) ? 0 : -1;
+}
+
+
+int
+InfHostOpenFile(PHINF InfHandle,
+                const CHAR *FileName,
+                LANGID LanguageId,
+                ULONG *ErrorLine)
+{
+  FILE *File;
+  CHAR *FileBuffer;
+  ULONG FileLength;
+  ULONG FileBufferLength;
+  PINFCACHE Cache;
+  INFSTATUS Status = INF_STATUS_SUCCESS;
+
+  *InfHandle = NULL;
+  *ErrorLine = (ULONG)-1;
+
+  /* Open the inf file */
+  File = fopen(FileName, "rb");
+  if (NULL == File)
+    {
+      DPRINT1("fopen() failed (errno %d)\n", errno);
+      return -1;
+    }
+
+  DPRINT("fopen() successful\n");
+
+  /* Query file size */
+  if (fseek(File, (size_t)0, SEEK_END))
+    {
+      DPRINT1("fseek() to EOF failed (errno %d)\n", errno);
+      fclose(File);
+      return -1;
+    }
+
+  FileLength = (ULONG)ftell(File);
+  if ((ULONG) -1 == FileLength)
+    {
+      DPRINT1("ftell() failed (errno %d)\n", errno);
+      fclose(File);
+      return -1;
+    }
+  DPRINT("File size: %u\n", (UINT)FileLength);
+
+  /* Rewind */
+  if (fseek(File, (size_t)0, SEEK_SET))
+    {
+      DPRINT1("fseek() to BOF failed (errno %d)\n", errno);
+      fclose(File);
+      return -1;
+    }
+
+  /* Allocate file buffer */
+  FileBufferLength = FileLength + 2;
+  FileBuffer = MALLOC(FileBufferLength);
+  if (FileBuffer == NULL)
+    {
+      DPRINT1("MALLOC() failed\n");
+      fclose(File);
+      return -1;
+    }
+
+  /* Read file */
+  if (FileLength != fread(FileBuffer, (size_t)1, (size_t)FileLength, File))
+    {
+      DPRINT1("fread() failed (errno %d)\n", errno);
+      fclose(File);
+      return -1;
+    }
+
+  fclose(File);
+
+  /* Append string terminator */
+  FileBuffer[FileLength] = 0;
+  FileBuffer[FileLength + 1] = 0;
+
+  /* Allocate infcache header */
+  Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
+  if (Cache == NULL)
+    {
+      DPRINT1("MALLOC() failed\n");
+      FREE(FileBuffer);
+      return -1;
+    }
+
+  /* Initialize inicache header */
+  ZEROMEMORY(Cache,
+             sizeof(INFCACHE));
+
+    Cache->LanguageId = LanguageId;
+
+  /* Parse the inf buffer */
+    if (!RtlIsTextUnicode(FileBuffer, (INT)FileBufferLength, NULL))
+    {
+//        static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
+        WCHAR *new_buff;
+//        UINT codepage = CP_ACP;
+        UINT offset = 0;
+
+//        if (FileLength > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
+//        {
+//            codepage = CP_UTF8;
+//            offset = sizeof(utf8_bom);
+//        }
+
+        new_buff = MALLOC(FileBufferLength * sizeof(WCHAR));
+        if (new_buff != NULL)
+        {
+            ULONG len;
+            Status = RtlMultiByteToUnicodeN(new_buff,
+                                            FileBufferLength * sizeof(WCHAR),
+                                            &len,
+                                            (char *)FileBuffer + offset,
+                                            FileBufferLength - offset);
+
+            Status = InfpParseBuffer(Cache,
+                                     new_buff,
+                                     new_buff + len / sizeof(WCHAR),
+                                     ErrorLine);
+
+            FREE(new_buff);
+        }
+        else
+            Status = INF_STATUS_INSUFFICIENT_RESOURCES;
+    }
+    else
+    {
+        WCHAR *new_buff = (WCHAR *)FileBuffer;
+        /* UCS-16 files should start with the Unicode BOM; we should skip it */
+        if (*new_buff == 0xfeff)
+        {
+            new_buff++;
+            FileBufferLength -= sizeof(WCHAR);
+        }
+        Status = InfpParseBuffer(Cache,
+                                 new_buff,
+                                 (WCHAR*)((char*)new_buff + FileBufferLength),
+                                 ErrorLine);
+    }
+
+  if (!INF_SUCCESS(Status))
+    {
+      FREE(Cache);
+      Cache = NULL;
+    }
+
+  /* Free file buffer */
+  FREE(FileBuffer);
+
+  *InfHandle = (HINF)Cache;
+
+  return INF_SUCCESS(Status) ? 0 : -1;
+}
+
+
+void
+InfHostCloseFile(HINF InfHandle)
+{
+  PINFCACHE Cache;
+
+  Cache = (PINFCACHE)InfHandle;
+
+  if (Cache == NULL)
+    {
+      return;
+    }
+
+  while (Cache->FirstSection != NULL)
+    {
+      Cache->FirstSection = InfpFreeSection(Cache->FirstSection);
+    }
+  Cache->LastSection = NULL;
+
+  FREE(Cache);
+}
+
+/* EOF */
diff --git a/lib/newinflib/infhostget.c b/lib/newinflib/infhostget.c
new file mode 100644 (file)
index 0000000..bd49be1
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ *             Eric Kohl
+ *             Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+#include "infhost.h"
+
+#define NDEBUG
+#include <debug.h>
+
+int
+InfHostFindFirstLine(HINF InfHandle,
+                     const WCHAR *Section,
+                     const WCHAR *Key,
+                     PINFCONTEXT *Context)
+{
+  INFSTATUS Status;
+
+  Status = InfpFindFirstLine(InfHandle, Section, Key, Context);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+
+int
+InfHostFindNextLine(PINFCONTEXT ContextIn,
+                    PINFCONTEXT ContextOut)
+{
+  INFSTATUS Status;
+
+  Status = InfpFindNextLine(ContextIn, ContextOut);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+
+int
+InfHostFindFirstMatchLine(PINFCONTEXT ContextIn,
+                          const WCHAR *Key,
+                          PINFCONTEXT ContextOut)
+{
+  INFSTATUS Status;
+
+  Status = InfpFindFirstMatchLine(ContextIn, Key, ContextOut);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+
+int
+InfHostFindNextMatchLine(PINFCONTEXT ContextIn,
+                         const WCHAR *Key,
+                         PINFCONTEXT ContextOut)
+{
+  INFSTATUS Status;
+
+  Status = InfpFindNextMatchLine(ContextIn, Key, ContextOut);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+
+LONG
+InfHostGetLineCount(HINF InfHandle,
+                    PCWSTR Section)
+{
+  return InfpGetLineCount(InfHandle, Section);
+}
+
+
+/* InfGetLineText */
+
+
+LONG
+InfHostGetFieldCount(PINFCONTEXT Context)
+{
+  return InfpGetFieldCount(Context);
+}
+
+
+int
+InfHostGetBinaryField(PINFCONTEXT Context,
+                      ULONG FieldIndex,
+                      UCHAR *ReturnBuffer,
+                      ULONG ReturnBufferSize,
+                      ULONG *RequiredSize)
+{
+  INFSTATUS Status;
+
+  Status = InfpGetBinaryField(Context, FieldIndex, ReturnBuffer,
+                              ReturnBufferSize, RequiredSize);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+
+int
+InfHostGetIntField(PINFCONTEXT Context,
+                   ULONG FieldIndex,
+                   ULONG *IntegerValue)
+{
+  INFSTATUS Status;
+
+  Status = InfpGetIntField(Context, FieldIndex, (PLONG)IntegerValue);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+
+int
+InfHostGetMultiSzField(PINFCONTEXT Context,
+                       ULONG FieldIndex,
+                       WCHAR *ReturnBuffer,
+                       ULONG ReturnBufferSize,
+                       ULONG *RequiredSize)
+{
+  INFSTATUS Status;
+
+  Status = InfpGetMultiSzField(Context, FieldIndex, ReturnBuffer,
+                               ReturnBufferSize, RequiredSize);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+
+int
+InfHostGetStringField(PINFCONTEXT Context,
+                      ULONG FieldIndex,
+                      WCHAR *ReturnBuffer,
+                      ULONG ReturnBufferSize,
+                      ULONG *RequiredSize)
+{
+  INFSTATUS Status;
+
+  Status = InfpGetStringField(Context, FieldIndex, ReturnBuffer,
+                              ReturnBufferSize, RequiredSize);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+
+int
+InfHostGetData(PINFCONTEXT Context,
+               WCHAR **Key,
+               WCHAR **Data)
+{
+  INFSTATUS Status;
+
+  Status = InfpGetData(Context, Key, Data);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+
+int
+InfHostGetDataField(PINFCONTEXT Context,
+                    ULONG FieldIndex,
+                    WCHAR **Data)
+{
+  INFSTATUS Status;
+
+  Status = InfpGetDataField(Context, FieldIndex, Data);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+VOID
+InfHostFreeContext(PINFCONTEXT Context)
+{
+  InfpFreeContext(Context);
+}
+
+/* EOF */
diff --git a/lib/newinflib/infhostput.c b/lib/newinflib/infhostput.c
new file mode 100644 (file)
index 0000000..a5233e5
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * COPYRIGHT:  Copyright 2005 Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+#include "infhost.h"
+
+#define NDEBUG
+#include <debug.h>
+
+int
+InfHostWriteFile(HINF InfHandle,
+                 const CHAR *FileName,
+                 const CHAR *HeaderComment)
+{
+  WCHAR *Buffer;
+  ULONG BufferSize;
+  INFSTATUS Status;
+  FILE *File;
+
+  Status = InfpBuildFileBuffer((PINFCACHE) InfHandle, &Buffer, &BufferSize);
+  if (! INF_SUCCESS(Status))
+    {
+      errno = Status;
+      return -1;
+    }
+
+  File = fopen(FileName, "wb");
+  if (NULL == File)
+    {
+      FREE(Buffer);
+      DPRINT1("fopen() failed (errno %d)\n", errno);
+      return -1;
+    }
+
+  DPRINT("fopen() successful\n");
+
+  if (NULL != HeaderComment && '\0' != *HeaderComment)
+    {
+//      fprintf(File, "; %s\r\n\r\n", HeaderComment);
+    }
+
+  if (BufferSize != fwrite(Buffer, (size_t)1, (size_t)BufferSize, File))
+    {
+      DPRINT1("fwrite() failed (errno %d)\n", errno);
+      fclose(File);
+      FREE(Buffer);
+      return -1;
+    }
+
+  fclose(File);
+
+  FREE(Buffer);
+
+  return 0;
+}
+
+int
+InfHostFindOrAddSection(HINF InfHandle,
+                        const WCHAR *Section,
+                        PINFCONTEXT *Context)
+{
+  INFSTATUS Status;
+
+  Status = InfpFindOrAddSection((PINFCACHE) InfHandle, Section, Context);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+int
+InfHostAddLine(PINFCONTEXT Context, const WCHAR *Key)
+{
+  INFSTATUS Status;
+
+  Status = InfpAddLineWithKey(Context, Key);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+int
+InfHostAddField(PINFCONTEXT Context, const WCHAR *Data)
+{
+  INFSTATUS Status;
+
+  Status = InfpAddField(Context, Data);
+  if (INF_SUCCESS(Status))
+    {
+      return 0;
+    }
+  else
+    {
+      errno = Status;
+      return -1;
+    }
+}
+
+/* EOF */
diff --git a/lib/newinflib/infhostrtl.c b/lib/newinflib/infhostrtl.c
new file mode 100644 (file)
index 0000000..c62d40a
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ *             Eric Kohl
+ *             Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+#include "infhost.h"
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS NTAPI
+RtlMultiByteToUnicodeN(
+   IN PWCHAR UnicodeString,
+   IN ULONG UnicodeSize,
+   IN PULONG ResultSize,
+   IN PCSTR MbString,
+   IN ULONG MbSize)
+{
+    ULONG Size = 0;
+    ULONG i;
+    PUCHAR WideString;
+
+    /* single-byte code page */
+    if (MbSize > (UnicodeSize / sizeof(WCHAR)))
+        Size = UnicodeSize / sizeof(WCHAR);
+    else
+        Size = MbSize;
+
+    if (ResultSize != NULL)
+        *ResultSize = Size * sizeof(WCHAR);
+
+    WideString = (PUCHAR)UnicodeString;
+    for (i = 0; i <= Size; i++)
+    {
+        WideString[2 * i + 0] = (UCHAR)MbString[i];
+        WideString[2 * i + 1] = 0;
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
+BOOLEAN
+NTAPI
+RtlIsTextUnicode( PVOID buf, INT len, INT *pf )
+{
+    static const WCHAR std_control_chars[] = {'\r','\n','\t',' ',0x3000,0};
+    static const WCHAR byterev_control_chars[] = {0x0d00,0x0a00,0x0900,0x2000,0};
+    const WCHAR *s = buf;
+    int i;
+    unsigned int flags = MAXULONG, out_flags = 0;
+
+    if (len < sizeof(WCHAR))
+    {
+        /* FIXME: MSDN documents IS_TEXT_UNICODE_BUFFER_TOO_SMALL but there is no such thing... */
+        if (pf) *pf = 0;
+        return FALSE;
+    }
+    if (pf)
+        flags = (unsigned int)*pf;
+    /*
+     * Apply various tests to the text string. According to the
+     * docs, each test "passed" sets the corresponding flag in
+     * the output flags. But some of the tests are mutually
+     * exclusive, so I don't see how you could pass all tests ...
+     */
+
+    /* Check for an odd length ... pass if even. */
+    if (len & 1) out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
+
+    if (((char *)buf)[len - 1] == 0)
+        len--;  /* Windows seems to do something like that to avoid e.g. false IS_TEXT_UNICODE_NULL_BYTES  */
+
+    len /= (INT)sizeof(WCHAR);
+    /* Windows only checks the first 256 characters */
+    if (len > 256) len = 256;
+
+    /* Check for the special byte order unicode marks. */
+    if (*s == 0xFEFF) out_flags |= IS_TEXT_UNICODE_SIGNATURE;
+    if (*s == 0xFFFE) out_flags |= IS_TEXT_UNICODE_REVERSE_SIGNATURE;
+
+    /* apply some statistical analysis */
+    if (flags & IS_TEXT_UNICODE_STATISTICS)
+    {
+        int stats = 0;
+        /* FIXME: checks only for ASCII characters in the unicode stream */
+        for (i = 0; i < len; i++)
+        {
+            if (s[i] <= 255) stats++;
+        }
+        if (stats > len / 2)
+            out_flags |= IS_TEXT_UNICODE_STATISTICS;
+    }
+
+    /* Check for unicode NULL chars */
+    if (flags & IS_TEXT_UNICODE_NULL_BYTES)
+    {
+        for (i = 0; i < len; i++)
+        {
+            if (!(s[i] & 0xff) || !(s[i] >> 8))
+            {
+                out_flags |= IS_TEXT_UNICODE_NULL_BYTES;
+                break;
+            }
+        }
+    }
+
+    if (flags & IS_TEXT_UNICODE_CONTROLS)
+    {
+        for (i = 0; i < len; i++)
+        {
+            if (strchrW(std_control_chars, s[i]))
+            {
+                out_flags |= IS_TEXT_UNICODE_CONTROLS;
+                break;
+            }
+        }
+    }
+
+    if (flags & IS_TEXT_UNICODE_REVERSE_CONTROLS)
+    {
+        for (i = 0; i < len; i++)
+        {
+            if (strchrW(byterev_control_chars, s[i]))
+            {
+                out_flags |= IS_TEXT_UNICODE_REVERSE_CONTROLS;
+                break;
+            }
+        }
+    }
+
+    if (pf)
+    {
+        out_flags &= (unsigned int)*pf;
+        *pf = (INT)out_flags;
+    }
+    /* check for flags that indicate it's definitely not valid Unicode */
+    if (out_flags & (IS_TEXT_UNICODE_REVERSE_MASK | IS_TEXT_UNICODE_NOT_UNICODE_MASK)) return FALSE;
+    /* now check for invalid ASCII, and assume Unicode if so */
+    if (out_flags & IS_TEXT_UNICODE_NOT_ASCII_MASK) return TRUE;
+    /* now check for Unicode flags */
+    if (out_flags & IS_TEXT_UNICODE_UNICODE_MASK) return TRUE;
+    /* no flags set */
+    return FALSE;
+}
diff --git a/lib/newinflib/inflib.h b/lib/newinflib/inflib.h
new file mode 100644 (file)
index 0000000..7dff17f
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * COPYRIGHT:  Copyright 2005 Ge van Geldorp <gvg@reactos.org>
+ */
+
+#include <ctype.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "builddep.h"
+#include "infcommon.h"
+#include "infpriv.h"
+
+/* EOF */
diff --git a/lib/newinflib/inflib.mak b/lib/newinflib/inflib.mak
new file mode 100644 (file)
index 0000000..a0edbe2
--- /dev/null
@@ -0,0 +1,76 @@
+INFLIB_BASE = $(LIB_BASE_)newinflib
+INFLIB_BASE_ = $(INFLIB_BASE)$(SEP)
+INFLIB_INT = $(INTERMEDIATE_)$(INFLIB_BASE)_host
+INFLIB_INT_ = $(INTERMEDIATE_)$(INFLIB_BASE)_host$(SEP)
+INFLIB_OUT = $(OUTPUT_)$(INFLIB_BASE)_host
+INFLIB_OUT_ = $(OUTPUT_)$(INFLIB_BASE)_host$(SEP)
+
+$(INFLIB_INT): | $(LIB_INT)
+       $(ECHO_MKDIR)
+       ${mkdir} $@
+
+ifneq ($(INTERMEDIATE),$(OUTPUT))
+$(INFLIB_OUT): | $(OUTPUT_)$(LIB_BASE)
+       $(ECHO_MKDIR)
+       ${mkdir} $@
+endif
+
+INFLIB_HOST_TARGET = \
+       $(INFLIB_OUT)$(SEP)newinflib.a
+
+INFLIB_HOST_SOURCES = $(addprefix $(INFLIB_BASE_), \
+       infcore.c \
+       infget.c \
+       infput.c \
+       infhostgen.c \
+       infhostget.c \
+       infhostput.c \
+       infhostrtl.c \
+       )
+
+INFLIB_HOST_OBJECTS = \
+       $(subst $(INFLIB_BASE), $(INFLIB_INT), $(INFLIB_HOST_SOURCES:.c=.o))
+
+INFLIB_HOST_CFLAGS = -O3 -Wall -Wpointer-arith -Wconversion \
+  -Wstrict-prototypes -Wmissing-prototypes -DINFLIB_HOST \
+  -Iinclude/reactos -Iinclude $(HOST_CFLAGS)
+
+$(INFLIB_HOST_TARGET): $(INFLIB_HOST_OBJECTS) | $(INFLIB_OUT)
+       $(ECHO_HOSTAR)
+       $(host_ar) -r $@ $(INFLIB_HOST_OBJECTS)
+
+$(INFLIB_INT_)infcore.o: $(INFLIB_BASE_)infcore.c | $(INFLIB_INT)
+       $(ECHO_HOSTCC)
+       ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+$(INFLIB_INT_)infget.o: $(INFLIB_BASE_)infget.c | $(INFLIB_INT)
+       $(ECHO_HOSTCC)
+       ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+$(INFLIB_INT_)infput.o: $(INFLIB_BASE_)infput.c | $(INFLIB_INT)
+       $(ECHO_HOSTCC)
+       ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+$(INFLIB_INT_)infhostgen.o: $(INFLIB_BASE_)infhostgen.c | $(INFLIB_INT)
+       $(ECHO_HOSTCC)
+       ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+$(INFLIB_INT_)infhostget.o: $(INFLIB_BASE_)infhostget.c | $(INFLIB_INT)
+       $(ECHO_HOSTCC)
+       ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+$(INFLIB_INT_)infhostput.o: $(INFLIB_BASE_)infhostput.c | $(INFLIB_INT)
+       $(ECHO_HOSTCC)
+       ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+$(INFLIB_INT_)infhostrtl.o: $(INFLIB_BASE_)infhostrtl.c | $(INFLIB_INT)
+       $(ECHO_HOSTCC)
+       ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+.PHONY: newinflib_host
+newinflib_host: $(INFLIB_HOST_TARGET)
+
+.PHONY: newinflib_host_clean
+newinflib_host_clean:
+       -@$(rm) $(INFLIB_HOST_TARGET) $(INFLIB_HOST_OBJECTS) 2>$(NUL)
+clean: newinflib_host_clean
diff --git a/lib/newinflib/inflib.rbuild b/lib/newinflib/inflib.rbuild
new file mode 100644 (file)
index 0000000..7c758a7
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../tools/rbuild/project.dtd">
+<group>
+<module name="newinflib" type="staticlibrary">
+       <include base="newinflib">.</include>
+       <file>infcore.c</file>
+       <file>infget.c</file>
+       <file>infput.c</file>
+       <file>infrosgen.c</file>
+       <file>infrosget.c</file>
+       <file>infrosput.c</file>
+</module>
+<module name="newinflibhost" type="hoststaticlibrary" allowwarnings="true">
+       <define name="WINE_UNICODE_API">" "</define>
+       <include base="unicode" />
+       <include base="newinflibhost">.</include>
+       <define name="__NO_CTYPE_INLINES" />
+       <define name="USE_HOST_WCSFUNCS" />
+       <group compilerset="gcc">
+               <compilerflag>-Wwrite-strings</compilerflag>
+               <compilerflag>-Wpointer-arith</compilerflag>
+       </group>
+       <define name="INFLIB_HOST" />
+       <file>infcore.c</file>
+       <file>infget.c</file>
+       <file>infput.c</file>
+       <file>infhostgen.c</file>
+       <file>infhostget.c</file>
+       <file>infhostput.c</file>
+       <file>infhostrtl.c</file>
+</module>
+</group>
diff --git a/lib/newinflib/infpriv.h b/lib/newinflib/infpriv.h
new file mode 100644 (file)
index 0000000..c7adede
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ *             Eric Kohl
+ *             Ge van Geldorp <gvg@reactos.org>
+ */
+
+#pragma once
+
+#ifndef FIELD_OFFSET
+#define FIELD_OFFSET(t,f) ((ptrdiff_t)&(((t*)0)->f))
+#endif
+
+#define INF_STATUS_INSUFFICIENT_RESOURCES  ((INFSTATUS)0xC000009A)
+#define INF_STATUS_BAD_SECTION_NAME_LINE   ((INFSTATUS)0xC0700001)
+#define INF_STATUS_SECTION_NAME_TOO_LONG   ((INFSTATUS)0xC0700002)
+#define INF_STATUS_WRONG_INF_STYLE         ((INFSTATUS)0xC0700003)
+#define INF_STATUS_NOT_ENOUGH_MEMORY       ((INFSTATUS)0xC0700004)
+
+typedef struct _INFCACHEFIELD
+{
+  struct _INFCACHEFIELD *Next;
+  struct _INFCACHEFIELD *Prev;
+
+  WCHAR Data[1];
+} INFCACHEFIELD, *PINFCACHEFIELD;
+
+typedef struct _INFCACHELINE
+{
+  struct _INFCACHELINE *Next;
+  struct _INFCACHELINE *Prev;
+
+  LONG FieldCount;
+
+  PWCHAR Key;
+
+  PINFCACHEFIELD FirstField;
+  PINFCACHEFIELD LastField;
+
+} INFCACHELINE, *PINFCACHELINE;
+
+typedef struct _INFCACHESECTION
+{
+  struct _INFCACHESECTION *Next;
+  struct _INFCACHESECTION *Prev;
+
+  PINFCACHELINE FirstLine;
+  PINFCACHELINE LastLine;
+
+  LONG LineCount;
+
+  WCHAR Name[1];
+} INFCACHESECTION, *PINFCACHESECTION;
+
+typedef struct _INFCACHE
+{
+  LANGID LanguageId;
+  PINFCACHESECTION FirstSection;
+  PINFCACHESECTION LastSection;
+
+  PINFCACHESECTION StringsSection;
+} INFCACHE, *PINFCACHE;
+
+typedef struct _INFCONTEXT
+{
+  PINFCACHE Inf;
+  PINFCACHESECTION Section;
+  PINFCACHELINE Line;
+} INFCONTEXT;
+
+typedef int INFSTATUS;
+
+/* FUNCTIONS ****************************************************************/
+
+extern INFSTATUS InfpParseBuffer(PINFCACHE file,
+                                 const WCHAR *buffer,
+                                 const WCHAR *end,
+                                 PULONG error_line);
+extern PINFCACHESECTION InfpFreeSection(PINFCACHESECTION Section);
+extern PINFCACHESECTION InfpAddSection(PINFCACHE Cache,
+                                       PCWSTR Name);
+extern PINFCACHELINE InfpAddLine(PINFCACHESECTION Section);
+extern PVOID InfpAddKeyToLine(PINFCACHELINE Line,
+                              PCWSTR Key);
+extern PVOID InfpAddFieldToLine(PINFCACHELINE Line,
+                                PCWSTR Data);
+extern PINFCACHELINE InfpFindKeyLine(PINFCACHESECTION Section,
+                                     PCWSTR Key);
+extern PINFCACHESECTION InfpFindSection(PINFCACHE Cache,
+                                        PCWSTR Section);
+
+extern INFSTATUS InfpBuildFileBuffer(PINFCACHE InfHandle,
+                                     PWCHAR *Buffer,
+                                     PULONG BufferSize);
+
+extern INFSTATUS InfpFindFirstLine(PINFCACHE InfHandle,
+                                   PCWSTR Section,
+                                   PCWSTR Key,
+                                   PINFCONTEXT *Context);
+extern INFSTATUS InfpFindNextLine(PINFCONTEXT ContextIn,
+                                  PINFCONTEXT ContextOut);
+extern INFSTATUS InfpFindFirstMatchLine(PINFCONTEXT ContextIn,
+                                        PCWSTR Key,
+                                        PINFCONTEXT ContextOut);
+extern INFSTATUS InfpFindNextMatchLine(PINFCONTEXT ContextIn,
+                                       PCWSTR Key,
+                                       PINFCONTEXT ContextOut);
+extern LONG InfpGetLineCount(HINF InfHandle,
+                             PCWSTR Section);
+extern LONG InfpGetFieldCount(PINFCONTEXT Context);
+extern INFSTATUS InfpGetBinaryField(PINFCONTEXT Context,
+                                    ULONG FieldIndex,
+                                    PUCHAR ReturnBuffer,
+                                    ULONG ReturnBufferSize,
+                                    PULONG RequiredSize);
+extern INFSTATUS InfpGetIntField(PINFCONTEXT Context,
+                                 ULONG FieldIndex,
+                                 PLONG IntegerValue);
+extern INFSTATUS InfpGetMultiSzField(PINFCONTEXT Context,
+                                     ULONG FieldIndex,
+                                     PWSTR ReturnBuffer,
+                                     ULONG ReturnBufferSize,
+                                     PULONG RequiredSize);
+extern INFSTATUS InfpGetStringField(PINFCONTEXT Context,
+                                    ULONG FieldIndex,
+                                    PWSTR ReturnBuffer,
+                                    ULONG ReturnBufferSize,
+                                    PULONG RequiredSize);
+extern INFSTATUS InfpGetData(PINFCONTEXT Context,
+                             PWCHAR *Key,
+                             PWCHAR *Data);
+extern INFSTATUS InfpGetDataField(PINFCONTEXT Context,
+                                  ULONG FieldIndex,
+                                  PWCHAR *Data);
+
+extern INFSTATUS InfpFindOrAddSection(PINFCACHE Cache,
+                                      PCWSTR Section,
+                                      PINFCONTEXT *Context);
+extern INFSTATUS InfpAddLineWithKey(PINFCONTEXT Context, PCWSTR Key);
+extern INFSTATUS InfpAddField(PINFCONTEXT Context, PCWSTR Data);
+
+extern VOID InfpFreeContext(PINFCONTEXT Context);
+
+/* EOF */
diff --git a/lib/newinflib/infput.c b/lib/newinflib/infput.c
new file mode 100644 (file)
index 0000000..c049f3f
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * COPYRIGHT:  Copyright 2005 Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+
+#define NDEBUG
+#include <debug.h>
+
+#define EOL      L"\r\n"
+#define SIZE_INC 1024
+
+typedef struct _OUTPUTBUFFER
+{
+  PWCHAR Buffer;
+  PWCHAR Current;
+  ULONG TotalSize;
+  ULONG FreeSize;
+  INFSTATUS Status;
+} OUTPUTBUFFER, *POUTPUTBUFFER;
+
+static void
+Output(POUTPUTBUFFER OutBuf, PCWSTR Text)
+{
+  ULONG Length;
+  PWCHAR NewBuf;
+  ULONG NewSize;
+
+  /* Skip mode? */
+  if (! INF_SUCCESS(OutBuf->Status))
+    {
+      return;
+    }
+
+  /* Doesn't fit? */
+  Length = (ULONG)strlenW(Text) * sizeof(WCHAR);
+  if (OutBuf->FreeSize < Length + 1 && INF_SUCCESS(OutBuf->Status))
+    {
+      DPRINT("Out of free space. TotalSize %u FreeSize %u Length %u\n",
+             (UINT)OutBuf->TotalSize, (UINT)OutBuf->FreeSize, (UINT)Length);
+      /* Round up to next SIZE_INC */
+      NewSize = OutBuf->TotalSize +
+                (((Length + 1) - OutBuf->FreeSize + (SIZE_INC - 1)) /
+                 SIZE_INC) * SIZE_INC;
+      DPRINT("NewSize %u\n", (UINT)NewSize);
+      NewBuf = MALLOC(NewSize);
+      /* Abort if failed */
+      if (NULL == NewBuf)
+        {
+          DPRINT1("MALLOC() failed\n");
+          OutBuf->Status = INF_STATUS_NO_MEMORY;
+          return;
+        }
+      
+      /* Need to copy old contents? */
+      if (NULL != OutBuf->Buffer)
+        {
+          DPRINT("Copying %u bytes from old content\n",
+                 (UINT)(OutBuf->TotalSize - OutBuf->FreeSize));
+          MEMCPY(NewBuf, OutBuf->Buffer, OutBuf->TotalSize - OutBuf->FreeSize);
+          OutBuf->Current = NewBuf + (OutBuf->Current - OutBuf->Buffer);
+          FREE(OutBuf->Buffer);
+        }
+      else
+        {
+          OutBuf->Current = NewBuf;
+        }
+      OutBuf->Buffer = NewBuf;
+      OutBuf->FreeSize += NewSize - OutBuf->TotalSize;
+      OutBuf->TotalSize = NewSize;
+      DPRINT("After reallocation TotalSize %u FreeSize %u\n",
+             (UINT)OutBuf->TotalSize, (UINT)OutBuf->FreeSize);
+    }
+
+  /* We're guaranteed to have enough room now. Copy char by char because of
+     possible "conversion" from Unicode to Ansi */
+  while (Length--)
+    {
+      *OutBuf->Current++ = *Text++;
+      OutBuf->FreeSize--;
+    }
+  *OutBuf->Current = '\0';
+}
+
+INFSTATUS
+InfpBuildFileBuffer(PINFCACHE Cache,
+                    PWCHAR *Buffer,
+                    PULONG BufferSize)
+{
+  OUTPUTBUFFER OutBuf;
+  PINFCACHESECTION CacheSection;
+  PINFCACHELINE CacheLine;
+  PINFCACHEFIELD CacheField;
+  PWCHAR p;
+  BOOLEAN NeedQuotes;
+
+  OutBuf.Buffer = NULL;
+  OutBuf.Current = NULL;
+  OutBuf.FreeSize = 0;
+  OutBuf.TotalSize = 0;
+  OutBuf.Status = INF_STATUS_SUCCESS;
+
+  /* Iterate through list of sections */
+  CacheSection = Cache->FirstSection;
+  while (CacheSection != NULL)
+    {
+      DPRINT("Processing section %S\n", CacheSection->Name);
+      if (CacheSection != Cache->FirstSection)
+        {
+          Output(&OutBuf, EOL);
+        }
+      Output(&OutBuf, L"[");
+      Output(&OutBuf, CacheSection->Name);
+      Output(&OutBuf, L"]");
+      Output(&OutBuf, EOL);
+
+      /* Iterate through list of lines */
+      CacheLine = CacheSection->FirstLine;
+      while (CacheLine != NULL)
+        {
+          if (NULL != CacheLine->Key)
+            {
+              DPRINT("Line with key %S\n", CacheLine->Key);
+              Output(&OutBuf, CacheLine->Key);
+              Output(&OutBuf, L" = ");
+            }
+          else
+            {
+              DPRINT("Line without key\n");
+            }
+
+          /* Iterate through list of lines */
+          CacheField = CacheLine->FirstField;
+          while (CacheField != NULL)
+            {
+              if (CacheField != CacheLine->FirstField)
+                {
+                  Output(&OutBuf, L",");
+                }
+              p = CacheField->Data;
+              NeedQuotes = FALSE;
+              while (L'\0' != *p && ! NeedQuotes)
+                {
+                  NeedQuotes = (BOOLEAN)(L',' == *p || L';' == *p ||
+                                         L'\\' == *p);
+                  p++;
+                }
+              if (NeedQuotes)
+                {
+                  Output(&OutBuf, L"\"");
+                  Output(&OutBuf, CacheField->Data);
+                  Output(&OutBuf, L"\"");
+                }
+              else
+                {
+                  Output(&OutBuf, CacheField->Data);
+                }
+
+              /* Get the next field */
+              CacheField = CacheField->Next;
+            }
+
+          Output(&OutBuf, EOL);
+          /* Get the next line */
+          CacheLine = CacheLine->Next;
+        }
+
+      /* Get the next section */
+      CacheSection = CacheSection->Next;
+    }
+
+  if (INF_SUCCESS(OutBuf.Status))
+    {
+      *Buffer = OutBuf.Buffer;
+      *BufferSize = OutBuf.TotalSize - OutBuf.FreeSize;
+    }
+  else if (NULL != OutBuf.Buffer)
+    {
+      FREE(OutBuf.Buffer);
+    }
+
+  return INF_STATUS_SUCCESS;
+}
+
+INFSTATUS
+InfpFindOrAddSection(PINFCACHE Cache,
+                     PCWSTR Section,
+                     PINFCONTEXT *Context)
+{
+  DPRINT("InfpFindOrAddSection section %S\n", Section);
+
+  *Context = MALLOC(sizeof(INFCONTEXT));
+  if (NULL == *Context)
+    {
+      DPRINT1("MALLOC() failed\n");
+      return INF_STATUS_NO_MEMORY;
+    }
+
+  (*Context)->Inf = Cache;
+  (*Context)->Section = InfpFindSection(Cache, Section);
+  (*Context)->Line = NULL;
+  if (NULL == (*Context)->Section)
+    {
+      DPRINT("Section not found, creating it\n");
+      (*Context)->Section = InfpAddSection(Cache, Section);
+      if (NULL == (*Context)->Section)
+        {
+          DPRINT("Failed to create section\n");
+          FREE(*Context);
+          return INF_STATUS_NO_MEMORY;
+        }
+    }
+
+  return INF_STATUS_SUCCESS;
+}
+
+INFSTATUS
+InfpAddLineWithKey(PINFCONTEXT Context, PCWSTR Key)
+{
+  if (NULL == Context)
+    {
+      DPRINT1("Invalid parameter\n");
+      return INF_STATUS_INVALID_PARAMETER;
+    }
+
+  Context->Line = InfpAddLine(Context->Section);
+  if (NULL == Context->Line)
+    {
+      DPRINT("Failed to create line\n");
+      return INF_STATUS_NO_MEMORY;
+    }
+
+  if (NULL != Key && NULL == InfpAddKeyToLine(Context->Line, Key))
+    {
+      DPRINT("Failed to add key\n");
+      return INF_STATUS_NO_MEMORY;
+    }
+
+  return INF_STATUS_SUCCESS;
+}
+
+INFSTATUS
+InfpAddField(PINFCONTEXT Context, PCWSTR Data)
+{
+  if (NULL == Context || NULL == Context->Line)
+    {
+      DPRINT1("Invalid parameter\n");
+      return INF_STATUS_INVALID_PARAMETER;
+    }
+
+  if (NULL == InfpAddFieldToLine(Context->Line, Data))
+    {
+      DPRINT("Failed to add field\n");
+      return INF_STATUS_NO_MEMORY;
+    }
+
+  return INF_STATUS_SUCCESS;
+}
+
+/* EOF */
diff --git a/lib/newinflib/infros.h b/lib/newinflib/infros.h
new file mode 100644 (file)
index 0000000..92dbc51
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ *             Eric Kohl
+ *             Ge van Geldorp <gvg@reactos.org>
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <infcommon.h>
+
+extern VOID InfSetHeap(PVOID Heap);
+extern NTSTATUS InfOpenBufferedFile(PHINF InfHandle,
+                                    PVOID Buffer,
+                                    ULONG BufferSize,
+                                    LANGID LanguageId,
+                                    PULONG ErrorLine);
+extern NTSTATUS InfOpenFile(PHINF InfHandle,
+                            PUNICODE_STRING FileName,
+                            LANGID LanguageId,
+                            PULONG ErrorLine);
+extern NTSTATUS InfWriteFile(HINF InfHandle,
+                             PUNICODE_STRING FileName,
+                             PUNICODE_STRING HeaderComment);
+extern VOID InfCloseFile(HINF InfHandle);
+extern BOOLEAN InfFindFirstLine(HINF InfHandle,
+                                PCWSTR Section,
+                                PCWSTR Key,
+                                PINFCONTEXT *Context);
+extern BOOLEAN InfFindNextLine(PINFCONTEXT ContextIn,
+                               PINFCONTEXT ContextOut);
+extern BOOLEAN InfFindFirstMatchLine(PINFCONTEXT ContextIn,
+                                     PCWSTR Key,
+                                     PINFCONTEXT ContextOut);
+extern BOOLEAN InfFindNextMatchLine(PINFCONTEXT ContextIn,
+                                    PCWSTR Key,
+                                    PINFCONTEXT ContextOut);
+extern LONG InfGetLineCount(HINF InfHandle,
+                            PCWSTR Section);
+extern LONG InfGetFieldCount(PINFCONTEXT Context);
+extern BOOLEAN InfGetBinaryField(PINFCONTEXT Context,
+                                 ULONG FieldIndex,
+                                 PUCHAR ReturnBuffer,
+                                 ULONG ReturnBufferSize,
+                                 PULONG RequiredSize);
+extern BOOLEAN InfGetIntField(PINFCONTEXT Context,
+                              ULONG FieldIndex,
+                              PLONG IntegerValue);
+extern BOOLEAN InfGetMultiSzField(PINFCONTEXT Context,
+                                  ULONG FieldIndex,
+                                  PWSTR ReturnBuffer,
+                                  ULONG ReturnBufferSize,
+                                  PULONG RequiredSize);
+extern BOOLEAN InfGetStringField(PINFCONTEXT Context,
+                                 ULONG FieldIndex,
+                                 PWSTR ReturnBuffer,
+                                 ULONG ReturnBufferSize,
+                                 PULONG RequiredSize);
+extern BOOLEAN InfGetData(PINFCONTEXT Context,
+                          PWCHAR *Key,
+                          PWCHAR *Data);
+extern BOOLEAN InfGetDataField(PINFCONTEXT Context,
+                               ULONG FieldIndex,
+                               PWCHAR *Data);
+extern BOOLEAN InfFindOrAddSection(HINF InfHandle,
+                                   PCWSTR Section,
+                                   PINFCONTEXT *Context);
+extern BOOLEAN InfAddLine(PINFCONTEXT Context, PCWSTR Key);
+extern BOOLEAN InfAddField(PINFCONTEXT Context, PCWSTR Data);
+extern VOID InfFreeContext(PINFCONTEXT Context);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/* EOF */
diff --git a/lib/newinflib/infrosgen.c b/lib/newinflib/infrosgen.c
new file mode 100644 (file)
index 0000000..b23403b
--- /dev/null
@@ -0,0 +1,365 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ *             Eric Kohl
+ *             Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+#include "infros.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* PRIVATE FUNCTIONS ********************************************************/
+
+static int InfpHeapRefCount;
+
+static VOID
+CheckHeap()
+{
+  if (NULL == InfpHeap)
+    {
+      InfpHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL);
+    }
+  if (0 <= InfpHeapRefCount)
+    {
+      InfpHeapRefCount++;
+    }
+}
+
+
+/* PUBLIC FUNCTIONS *********************************************************/
+
+PVOID InfpHeap;
+
+VOID
+InfSetHeap(PVOID Heap)
+{
+  if (NULL == InfpHeap)
+    {
+      InfpHeap = Heap;
+      InfpHeapRefCount = -1;
+    }
+}
+
+
+NTSTATUS
+InfOpenBufferedFile(PHINF InfHandle,
+                    PVOID Buffer,
+                    ULONG BufferSize,
+                    LANGID LanguageId,
+                    PULONG ErrorLine)
+{
+  INFSTATUS Status;
+  PINFCACHE Cache;
+  PCHAR FileBuffer;
+  ULONG FileBufferSize;
+
+  CheckHeap();
+
+  *InfHandle = NULL;
+  *ErrorLine = (ULONG)-1;
+
+  /* Allocate file buffer */
+  FileBufferSize = BufferSize + 2;
+  FileBuffer = MALLOC(FileBufferSize);
+  if (FileBuffer == NULL)
+    {
+      DPRINT1("MALLOC() failed\n");
+      return(INF_STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+  MEMCPY(FileBuffer, Buffer, BufferSize);
+
+  /* Append string terminator */
+  FileBuffer[BufferSize] = 0;
+  FileBuffer[BufferSize + 1] = 0;
+
+  /* Allocate infcache header */
+  Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
+  if (Cache == NULL)
+    {
+      DPRINT("MALLOC() failed\n");
+      FREE(FileBuffer);
+      return(INF_STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+  /* Initialize inicache header */
+  ZEROMEMORY(Cache,
+             sizeof(INFCACHE));
+
+    Cache->LanguageId = LanguageId;
+
+    /* Parse the inf buffer */
+    if (!RtlIsTextUnicode(FileBuffer, FileBufferSize, NULL))
+    {
+//        static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
+        WCHAR *new_buff;
+//        UINT codepage = CP_ACP;
+        UINT offset = 0;
+
+//        if (BufferSize > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
+//        {
+//            codepage = CP_UTF8;
+//            offset = sizeof(utf8_bom);
+//        }
+
+        new_buff = MALLOC(FileBufferSize * sizeof(WCHAR));
+        if (new_buff != NULL)
+        {
+            ULONG len;
+            Status = RtlMultiByteToUnicodeN(new_buff,
+                                            FileBufferSize * sizeof(WCHAR),
+                                            &len,
+                                            (char *)FileBuffer + offset,
+                                            FileBufferSize - offset);
+
+            Status = InfpParseBuffer(Cache,
+                                     new_buff,
+                                     new_buff + len / sizeof(WCHAR),
+                                     ErrorLine);
+            FREE(new_buff);
+        }
+        else
+            Status = INF_STATUS_INSUFFICIENT_RESOURCES;
+    }
+    else
+    {
+        WCHAR *new_buff = (WCHAR *)FileBuffer;
+        /* UCS-16 files should start with the Unicode BOM; we should skip it */
+        if (*new_buff == 0xfeff)
+        {
+            new_buff++;
+            FileBufferSize -= sizeof(WCHAR);
+        }
+        Status = InfpParseBuffer(Cache,
+                                 new_buff,
+                                 (WCHAR*)((char*)new_buff + FileBufferSize),
+                                 ErrorLine);
+    }
+
+  if (!INF_SUCCESS(Status))
+    {
+      FREE(Cache);
+      Cache = NULL;
+    }
+
+  /* Free file buffer */
+  FREE(FileBuffer);
+
+  *InfHandle = (HINF)Cache;
+
+  return(Status);
+}
+
+
+NTSTATUS
+InfOpenFile(PHINF InfHandle,
+           PUNICODE_STRING FileName,
+           LANGID LanguageId,
+           PULONG ErrorLine)
+{
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  FILE_STANDARD_INFORMATION FileInfo;
+  IO_STATUS_BLOCK IoStatusBlock;
+  HANDLE FileHandle;
+  NTSTATUS Status;
+  PCHAR FileBuffer;
+  ULONG FileLength;
+  ULONG FileBufferLength;
+  LARGE_INTEGER FileOffset;
+  PINFCACHE Cache;
+
+  CheckHeap();
+
+  *InfHandle = NULL;
+  *ErrorLine = (ULONG)-1;
+
+  /* Open the inf file */
+  InitializeObjectAttributes(&ObjectAttributes,
+                            FileName,
+                            0,
+                            NULL,
+                            NULL);
+
+  Status = NtOpenFile(&FileHandle,
+                     GENERIC_READ | SYNCHRONIZE,
+                     &ObjectAttributes,
+                     &IoStatusBlock,
+                     FILE_SHARE_READ,
+                     FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+  if (!INF_SUCCESS(Status))
+    {
+      DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
+      return(Status);
+    }
+
+  DPRINT("NtOpenFile() successful\n");
+
+  /* Query file size */
+  Status = NtQueryInformationFile(FileHandle,
+                                 &IoStatusBlock,
+                                 &FileInfo,
+                                 sizeof(FILE_STANDARD_INFORMATION),
+                                 FileStandardInformation);
+  if (!INF_SUCCESS(Status))
+    {
+      DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
+      NtClose(FileHandle);
+      return(Status);
+    }
+
+  FileLength = FileInfo.EndOfFile.u.LowPart;
+
+  DPRINT("File size: %lu\n", FileLength);
+
+  /* Allocate file buffer */
+  FileBufferLength = FileLength + 2;
+  FileBuffer = MALLOC(FileBufferLength);
+  if (FileBuffer == NULL)
+    {
+      DPRINT1("MALLOC() failed\n");
+      NtClose(FileHandle);
+      return(INF_STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+  /* Read file */
+  FileOffset.QuadPart = 0ULL;
+  Status = NtReadFile(FileHandle,
+                     NULL,
+                     NULL,
+                     NULL,
+                     &IoStatusBlock,
+                     FileBuffer,
+                     FileLength,
+                     &FileOffset,
+                     NULL);
+
+  /* Append string terminator */
+  FileBuffer[FileLength] = 0;
+  FileBuffer[FileLength + 1] = 0;
+
+  NtClose(FileHandle);
+
+  if (!INF_SUCCESS(Status))
+    {
+      DPRINT("NtReadFile() failed (Status %lx)\n", Status);
+      FREE(FileBuffer);
+      return(Status);
+    }
+
+  /* Allocate infcache header */
+  Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
+  if (Cache == NULL)
+    {
+      DPRINT("MALLOC() failed\n");
+      FREE(FileBuffer);
+      return(INF_STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+  /* Initialize inicache header */
+  ZEROMEMORY(Cache,
+             sizeof(INFCACHE));
+
+    Cache->LanguageId = LanguageId;
+
+    /* Parse the inf buffer */
+    if (!RtlIsTextUnicode(FileBuffer, FileBufferLength, NULL))
+    {
+//        static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
+        WCHAR *new_buff;
+//        UINT codepage = CP_ACP;
+        UINT offset = 0;
+
+//        if (FileLength > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
+//        {
+//            codepage = CP_UTF8;
+//            offset = sizeof(utf8_bom);
+//        }
+
+        new_buff = MALLOC(FileBufferLength * sizeof(WCHAR));
+        if (new_buff != NULL)
+        {
+            ULONG len;
+            Status = RtlMultiByteToUnicodeN(new_buff,
+                                            FileBufferLength * sizeof(WCHAR),
+                                            &len,
+                                            (char *)FileBuffer + offset,
+                                            FileBufferLength - offset);
+
+            Status = InfpParseBuffer(Cache,
+                                     new_buff,
+                                     new_buff + len / sizeof(WCHAR),
+                                     ErrorLine);
+            FREE(new_buff);
+        }
+        else
+            Status = INF_STATUS_INSUFFICIENT_RESOURCES;
+    }
+    else
+    {
+        WCHAR *new_buff = (WCHAR *)FileBuffer;
+        /* UCS-16 files should start with the Unicode BOM; we should skip it */
+        if (*new_buff == 0xfeff)
+        {
+            new_buff++;
+            FileBufferLength -= sizeof(WCHAR);
+        }
+        Status = InfpParseBuffer(Cache,
+                                 new_buff,
+                                 (WCHAR*)((char*)new_buff + FileBufferLength),
+                                 ErrorLine);
+    }
+
+  if (!INF_SUCCESS(Status))
+    {
+      FREE(Cache);
+      Cache = NULL;
+    }
+
+  /* Free file buffer */
+  FREE(FileBuffer);
+
+  *InfHandle = (HINF)Cache;
+
+  return(Status);
+}
+
+
+VOID
+InfCloseFile(HINF InfHandle)
+{
+  PINFCACHE Cache;
+
+  Cache = (PINFCACHE)InfHandle;
+
+  if (Cache == NULL)
+    {
+      return;
+    }
+
+  while (Cache->FirstSection != NULL)
+    {
+      Cache->FirstSection = InfpFreeSection(Cache->FirstSection);
+    }
+  Cache->LastSection = NULL;
+
+  FREE(Cache);
+
+  if (0 < InfpHeapRefCount)
+    {
+      InfpHeapRefCount--;
+      if (0 == InfpHeapRefCount)
+        {
+          RtlDestroyHeap(InfpHeap);
+          InfpHeap = NULL;
+        }
+    }
+}
+
+
+/* EOF */
diff --git a/lib/newinflib/infrosget.c b/lib/newinflib/infrosget.c
new file mode 100644 (file)
index 0000000..9f3e7b0
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ *             Eric Kohl
+ *             Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+#include "infros.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+BOOLEAN
+InfFindFirstLine(HINF InfHandle,
+                 PCWSTR Section,
+                 PCWSTR Key,
+                 PINFCONTEXT *Context)
+{
+  return INF_SUCCESS(InfpFindFirstLine(InfHandle, Section, Key, Context));
+}
+
+
+BOOLEAN
+InfFindNextLine(PINFCONTEXT ContextIn,
+                 PINFCONTEXT ContextOut)
+{
+  return INF_SUCCESS(InfpFindNextLine(ContextIn, ContextOut));
+}
+
+
+BOOLEAN
+InfFindFirstMatchLine(PINFCONTEXT ContextIn,
+                      PCWSTR Key,
+                      PINFCONTEXT ContextOut)
+{
+  return INF_SUCCESS(InfpFindFirstMatchLine(ContextIn, Key, ContextOut));
+}
+
+
+BOOLEAN
+InfFindNextMatchLine(PINFCONTEXT ContextIn,
+                     PCWSTR Key,
+                     PINFCONTEXT ContextOut)
+{
+  return INF_SUCCESS(InfpFindNextMatchLine(ContextIn, Key, ContextOut));
+}
+
+
+LONG
+InfGetLineCount(HINF InfHandle,
+                PCWSTR Section)
+{
+  return InfpGetLineCount(InfHandle, Section);
+}
+
+
+/* InfGetLineText */
+
+
+LONG
+InfGetFieldCount(PINFCONTEXT Context)
+{
+  return InfpGetFieldCount(Context);
+}
+
+
+BOOLEAN
+InfGetBinaryField(PINFCONTEXT Context,
+                  ULONG FieldIndex,
+                  PUCHAR ReturnBuffer,
+                  ULONG ReturnBufferSize,
+                  PULONG RequiredSize)
+{
+  return INF_SUCCESS(InfpGetBinaryField(Context, FieldIndex, ReturnBuffer,
+                                        ReturnBufferSize, RequiredSize));
+}
+
+
+BOOLEAN
+InfGetIntField(PINFCONTEXT Context,
+               ULONG FieldIndex,
+               PLONG IntegerValue)
+{
+  return INF_SUCCESS(InfpGetIntField(Context, FieldIndex, IntegerValue));
+}
+
+
+BOOLEAN
+InfGetMultiSzField(PINFCONTEXT Context,
+                   ULONG FieldIndex,
+                   PWSTR ReturnBuffer,
+                   ULONG ReturnBufferSize,
+                   PULONG RequiredSize)
+{
+  return INF_SUCCESS(InfpGetMultiSzField(Context, FieldIndex, ReturnBuffer,
+                                         ReturnBufferSize, RequiredSize));
+}
+
+
+BOOLEAN
+InfGetStringField(PINFCONTEXT Context,
+                  ULONG FieldIndex,
+                  PWSTR ReturnBuffer,
+                  ULONG ReturnBufferSize,
+                  PULONG RequiredSize)
+{
+  return INF_SUCCESS(InfpGetStringField(Context, FieldIndex, ReturnBuffer,
+                                        ReturnBufferSize, RequiredSize));
+}
+
+
+BOOLEAN
+InfGetData(PINFCONTEXT Context,
+           PWCHAR *Key,
+           PWCHAR *Data)
+{
+  return INF_SUCCESS(InfpGetData(Context, Key, Data));
+}
+
+
+BOOLEAN
+InfGetDataField (PINFCONTEXT Context,
+                 ULONG FieldIndex,
+                 PWCHAR *Data)
+{
+  return INF_SUCCESS(InfpGetDataField(Context, FieldIndex, Data));
+}
+
+VOID
+InfFreeContext(PINFCONTEXT Context)
+{
+  InfpFreeContext(Context);
+}
+
+/* EOF */
diff --git a/lib/newinflib/infrosput.c b/lib/newinflib/infrosput.c
new file mode 100644 (file)
index 0000000..f5d3df9
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * PROJECT:    .inf file parser
+ * LICENSE:    GPL - See COPYING in the top level directory
+ * COPYRIGHT:  Copyright 2005 Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+#include "infros.h"
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS
+InfWriteFile(HINF InfHandle,
+             PUNICODE_STRING FileName,
+             PUNICODE_STRING HeaderComment)
+{
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  IO_STATUS_BLOCK IoStatusBlock;
+  HANDLE FileHandle;
+  NTSTATUS Status;
+  INFSTATUS InfStatus;
+  PWCHAR Buffer;
+  ULONG BufferSize;
+  PWCHAR HeaderBuffer;
+  ULONG HeaderBufferSize;
+  UINT Index;
+
+  InfStatus = InfpBuildFileBuffer((PINFCACHE) InfHandle, &Buffer, &BufferSize);
+  if (! INF_SUCCESS(InfStatus))
+    {
+      DPRINT("Failed to create buffer (Status 0x%lx)\n", InfStatus);
+      return InfStatus;
+    }
+
+  /* Open the inf file */
+  InitializeObjectAttributes(&ObjectAttributes,
+                             FileName,
+                             0,
+                             NULL,
+                             NULL);
+
+  Status = NtOpenFile(&FileHandle,
+                      GENERIC_WRITE | SYNCHRONIZE,
+                      &ObjectAttributes,
+                      &IoStatusBlock,
+                      0,
+                      FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+  if (!INF_SUCCESS(Status))
+    {
+      DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
+      FREE(Buffer);
+      return Status;
+    }
+
+  DPRINT("NtOpenFile() successful\n");
+
+  if (NULL != HeaderComment && 0 != HeaderComment->Length)
+    {
+      /* This is just a comment header, don't abort on errors here */
+      HeaderBufferSize = HeaderComment->Length + 7 * sizeof(WCHAR);
+      HeaderBuffer = MALLOC(HeaderBufferSize);
+      if (NULL != HeaderBuffer)
+        {
+          strcpyW(HeaderBuffer, L"; ");
+          for (Index = 0; Index < HeaderComment->Length / sizeof(WCHAR); Index++)
+            {
+              HeaderBuffer[2 + Index] = HeaderComment->Buffer[Index];
+            }
+          strcpyW(HeaderBuffer + (2 + HeaderComment->Length / sizeof(WCHAR)),
+                  L"\r\n\r\n");
+          NtWriteFile(FileHandle,
+                      NULL,
+                      NULL,
+                      NULL,
+                      &IoStatusBlock,
+                      HeaderBuffer,
+                      HeaderBufferSize,
+                      NULL,
+                      NULL);
+          FREE(HeaderBuffer);
+        }
+    }
+
+  /* Write main contents */
+  Status = NtWriteFile(FileHandle,
+                       NULL,
+                       NULL,
+                       NULL,
+                       &IoStatusBlock,
+                       Buffer,
+                       BufferSize,
+                       NULL,
+                       NULL);
+
+  NtClose(FileHandle);
+  FREE(Buffer);
+
+  if (!INF_SUCCESS(Status))
+    {
+      DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
+      FREE(Buffer);
+      return(Status);
+    }
+
+  return STATUS_SUCCESS;
+}
+
+BOOLEAN
+InfFindOrAddSection(HINF InfHandle,
+                    PCWSTR Section,
+                    PINFCONTEXT *Context)
+{
+  return INF_SUCCESS(InfpFindOrAddSection((PINFCACHE) InfHandle,
+                                          Section, Context));
+}
+
+BOOLEAN
+InfHostAddLine(PINFCONTEXT Context, PCWSTR Key)
+{
+  return INF_SUCCESS(InfpAddLineWithKey(Context, Key));
+}
+
+BOOLEAN
+InfHostAddField(PINFCONTEXT Context, PCWSTR Data)
+{
+  return INF_SUCCESS(InfpAddField(Context, Data));
+}
+
+/* EOF */
index a2b1783..065e260 100644 (file)
 /*
  * @implemented
  */
-NTSTATUS NTAPI
-RtlFindMessage(PVOID BaseAddress,
-              ULONG Type,
-              ULONG Language,
-              ULONG MessageId,
-              PRTL_MESSAGE_RESOURCE_ENTRY *MessageResourceEntry)
+NTSTATUS
+NTAPI
+RtlFindMessage(
+    PVOID BaseAddress,
+    ULONG Type,
+    ULONG Language,
+    ULONG MessageId,
+    PRTL_MESSAGE_RESOURCE_ENTRY *MessageResourceEntry)
 {
-   LDR_RESOURCE_INFO ResourceInfo;
-   PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
-   PRTL_MESSAGE_RESOURCE_DATA MessageTable;
-   NTSTATUS Status;
-   ULONG EntryOffset = 0, IdOffset = 0;
-   PRTL_MESSAGE_RESOURCE_ENTRY MessageEntry;
-   ULONG i;
-
-   DPRINT("RtlFindMessage()\n");
-
-   ResourceInfo.Type = Type;
-   ResourceInfo.Name = 1;
-   ResourceInfo.Language = Language;
-
-   Status = LdrFindResource_U(BaseAddress,
-                             &ResourceInfo,
-                             RESOURCE_DATA_LEVEL,
-                             &ResourceDataEntry);
-   if (!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-
-   DPRINT("ResourceDataEntry: %p\n", ResourceDataEntry);
-
-   Status = LdrAccessResource(BaseAddress,
-                             ResourceDataEntry,
-                             (PVOID*)&MessageTable,
-                             NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-
-   DPRINT("MessageTable: %p\n", MessageTable);
-
-   DPRINT("NumberOfBlocks %lu\n", MessageTable->NumberOfBlocks);
-   for (i = 0; i < MessageTable->NumberOfBlocks; i++)
-     {
-       DPRINT("LoId 0x%08lx  HiId 0x%08lx  Offset 0x%08lx\n",
-              MessageTable->Blocks[i].LowId,
-              MessageTable->Blocks[i].HighId,
-              MessageTable->Blocks[i].OffsetToEntries);
-     }
-
-   for (i = 0; i < MessageTable->NumberOfBlocks; i++)
-     {
-       if ((MessageId >= MessageTable->Blocks[i].LowId) &&
-           (MessageId <= MessageTable->Blocks[i].HighId))
-         {
-            EntryOffset = MessageTable->Blocks[i].OffsetToEntries;
-            IdOffset = MessageId - MessageTable->Blocks[i].LowId;
-            break;
-         }
-
-       if (MessageId < MessageTable->Blocks[i].LowId)
-         {
-            return STATUS_MESSAGE_NOT_FOUND;
-         }
-     }
-
-   if (MessageTable->NumberOfBlocks <= i)
-     {
-       return STATUS_MESSAGE_NOT_FOUND;
-     }
-
-   MessageEntry = (PRTL_MESSAGE_RESOURCE_ENTRY)((PUCHAR)MessageTable + MessageTable->Blocks[i].OffsetToEntries);
-
-   DPRINT("EntryOffset 0x%08lx\n", EntryOffset);
-   DPRINT("IdOffset 0x%08lx\n", IdOffset);
-
-   DPRINT("MessageEntry: %p\n", MessageEntry);
-   for (i = 0; i < IdOffset; i++)
-     {
-       MessageEntry = (PRTL_MESSAGE_RESOURCE_ENTRY)((PUCHAR)MessageEntry + (ULONG)MessageEntry->Length);
-     }
-
-   if (MessageEntry->Flags == 0)
-     {
-       DPRINT("AnsiText: %s\n", MessageEntry->Text);
-     }
-   else
-     {
-       DPRINT("UnicodeText: %S\n", (PWSTR)MessageEntry->Text);
-     }
-
-   if (MessageResourceEntry != NULL)
-     {
-       *MessageResourceEntry = MessageEntry;
-     }
-
-   return STATUS_SUCCESS;
+    LDR_RESOURCE_INFO ResourceInfo;
+    PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
+    PRTL_MESSAGE_RESOURCE_DATA MessageTable;
+    NTSTATUS Status;
+    ULONG EntryOffset = 0, IdOffset = 0;
+    PRTL_MESSAGE_RESOURCE_ENTRY MessageEntry;
+    ULONG i;
+
+    DPRINT("RtlFindMessage()\n");
+
+    ResourceInfo.Type = Type;
+    ResourceInfo.Name = 1;
+    ResourceInfo.Language = Language;
+
+    Status = LdrFindResource_U(BaseAddress,
+                               &ResourceInfo,
+                               RESOURCE_DATA_LEVEL,
+                               &ResourceDataEntry);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    DPRINT("ResourceDataEntry: %p\n", ResourceDataEntry);
+
+    Status = LdrAccessResource(BaseAddress,
+                               ResourceDataEntry,
+                               (PVOID*)&MessageTable,
+                               NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    DPRINT("MessageTable: %p\n", MessageTable);
+
+    DPRINT("NumberOfBlocks %lu\n", MessageTable->NumberOfBlocks);
+    for (i = 0; i < MessageTable->NumberOfBlocks; i++)
+    {
+        DPRINT("LoId 0x%08lx  HiId 0x%08lx  Offset 0x%08lx\n",
+               MessageTable->Blocks[i].LowId,
+               MessageTable->Blocks[i].HighId,
+               MessageTable->Blocks[i].OffsetToEntries);
+    }
+
+    for (i = 0; i < MessageTable->NumberOfBlocks; i++)
+    {
+        if ((MessageId >= MessageTable->Blocks[i].LowId) &&
+            (MessageId <= MessageTable->Blocks[i].HighId))
+        {
+            EntryOffset = MessageTable->Blocks[i].OffsetToEntries;
+            IdOffset = MessageId - MessageTable->Blocks[i].LowId;
+            break;
+        }
+
+        if (MessageId < MessageTable->Blocks[i].LowId)
+        {
+            return STATUS_MESSAGE_NOT_FOUND;
+        }
+    }
+
+    if (MessageTable->NumberOfBlocks <= i)
+    {
+        return STATUS_MESSAGE_NOT_FOUND;
+    }
+
+    MessageEntry = (PRTL_MESSAGE_RESOURCE_ENTRY)
+        ((PUCHAR)MessageTable + MessageTable->Blocks[i].OffsetToEntries);
+
+    DPRINT("EntryOffset 0x%08lx\n", EntryOffset);
+    DPRINT("IdOffset 0x%08lx\n", IdOffset);
+
+    DPRINT("MessageEntry: %p\n", MessageEntry);
+    for (i = 0; i < IdOffset; i++)
+    {
+        MessageEntry = (PRTL_MESSAGE_RESOURCE_ENTRY)
+            ((PUCHAR)MessageEntry + (ULONG)MessageEntry->Length);
+    }
+
+    if (MessageEntry->Flags == 0)
+    {
+        DPRINT("AnsiText: %s\n", MessageEntry->Text);
+    }
+    else
+    {
+        DPRINT("UnicodeText: %S\n", (PWSTR)MessageEntry->Text);
+    }
+
+    if (MessageResourceEntry != NULL)
+    {
+        *MessageResourceEntry = MessageEntry;
+    }
+
+    return STATUS_SUCCESS;
 }
 
 
@@ -139,22 +143,24 @@ RtlFindMessage(PVOID BaseAddress,
  *
  * @unimplemented
  */
-NTSTATUS NTAPI
-RtlFormatMessage(PWSTR Message,
-                UCHAR MaxWidth,
-                BOOLEAN IgnoreInserts,
-                BOOLEAN Ansi,
-                BOOLEAN ArgumentIsArray,
-                va_list *Arguments,
-                PWSTR Buffer,
-                ULONG BufferSize)
+NTSTATUS
+NTAPI
+RtlFormatMessage(
+    PWSTR Message,
+    UCHAR MaxWidth,
+    BOOLEAN IgnoreInserts,
+    BOOLEAN Ansi,
+    BOOLEAN ArgumentIsArray,
+    va_list *Arguments,
+    PWSTR Buffer,
+    ULONG BufferSize)
 {
-  DPRINT1("RtlFormatMessage(%S, %u, %s, %s, %s, %s, %p, %lu)\n",
-         Message, MaxWidth, IgnoreInserts ? "TRUE" : "FALSE", Ansi ? "TRUE" : "FALSE",
-         ArgumentIsArray ? "TRUE" : "FALSE", (PSTR)Arguments, Buffer, BufferSize);
+    DPRINT1("RtlFormatMessage(%S, %u, %s, %s, %s, %s, %p, %lu)\n",
+            Message, MaxWidth, IgnoreInserts ? "TRUE" : "FALSE", Ansi ? "TRUE" : "FALSE",
+            ArgumentIsArray ? "TRUE" : "FALSE", (PSTR)Arguments, Buffer, BufferSize);
 
-  UNIMPLEMENTED;
-  return STATUS_NOT_IMPLEMENTED;
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 /* EOF */
index 42aca6c..52f46f8 100644 (file)
 #define SPECIAL        32              /* 0x */
 #define LARGE  64              /* use 'ABCDEF' instead of 'abcdef' */
 #define REMOVEHEX      256             /* use 256 as remve 0x frim BASE 16  */
-typedef union {
-    struct {
-        unsigned int mantissal:32;
-        unsigned int mantissah:20;
-        unsigned int exponent:11;
-        unsigned int sign:1;
-    };
-    long long AsLongLong;
+typedef struct {
+    unsigned int mantissal:32;
+    unsigned int mantissah:20;
+    unsigned int exponent:11;
+    unsigned int sign:1;
 } double_t;
 
-/* We depend on this being true */
-C_ASSERT(sizeof(double_t) == sizeof(double));
-
 static
 __inline
 int
-_isinf(double_t x)
+_isinf(double __x)
 {
-       return ( x.exponent == 0x7ff  && ( x.mantissah == 0 && x.mantissal == 0 ));
+       union
+       {
+               double*   __x;
+               double_t*   x;
+       } x;
+
+       x.__x = &__x;
+       return ( x.x->exponent == 0x7ff  && ( x.x->mantissah == 0 && x.x->mantissal == 0 ));
 }
 
 static
 __inline
 int
-_isnan(double_t x)
+_isnan(double __x)
 {
-       return ( x.exponent == 0x7ff  && ( x.mantissah != 0 || x.mantissal != 0 ));
+       union
+       {
+               double*   __x;
+               double_t*   x;
+       } x;
+       x.__x = &__x;
+       return ( x.x->exponent == 0x7ff  && ( x.x->mantissah != 0 || x.x->mantissal != 0 ));
 }
 
 
@@ -173,13 +180,14 @@ number(char * buf, char * end, long long num, int base, int size, int precision,
 }
 
 static char *
-numberf(char * buf, char * end, double_t num, int base, int size, int precision, int type)
+numberf(char * buf, char * end, double num, int base, int size, int precision, int type)
 {
        char c,sign,tmp[66];
        const char *digits;
        const char *small_digits = "0123456789abcdefghijklmnopqrstuvwxyz";
        const char *large_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        int i;
+       long long x;
 
     /* FIXME
        the float version of number is direcly copy of number
@@ -193,9 +201,9 @@ numberf(char * buf, char * end, double_t num, int base, int size, int precision,
        c = (type & ZEROPAD) ? '0' : ' ';
        sign = 0;
        if (type & SIGN) {
-               if (num.sign) {
+               if (num < 0) {
                        sign = '-';
-                       num.sign = 0;
+                       num = -num;
                        size--;
                } else if (type & PLUS) {
                        sign = '+';
@@ -212,11 +220,15 @@ numberf(char * buf, char * end, double_t num, int base, int size, int precision,
                        size--;
        }
        i = 0;
-       if (num.AsLongLong == 0)
+       if (num == 0)
                tmp[i++] = '0';
-       else while (num.AsLongLong != 0)
+       else while (num != 0)
     {
-               tmp[i++] = digits[do_div(&num.AsLongLong,base)];
+        x = num;
+               tmp[i++] = digits[do_div(&x,base)];
+#ifndef _M_ARM // Missing __floatdidf in CeGCC 0.55 -- GCC 4.4
+               num=x;
+#endif
     }
        if (i > precision)
                precision = i;
@@ -377,7 +389,7 @@ int __cdecl _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args)
 {
        int len;
        unsigned long long num;
-       double_t _double;
+       double _double;
 
        int base;
        char *str, *end;
@@ -591,7 +603,7 @@ int __cdecl _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args)
                case 'f':
                case 'g':
                case 'G':
-          _double = va_arg(args, double_t);
+          _double = (double)va_arg(args, double);
          if ( _isnan(_double) ) {
             s = "Nan";
             len = 3;
@@ -622,7 +634,7 @@ int __cdecl _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args)
          } else {
             if ( precision == -1 )
                precision = 6;
-                       str = numberf(str, end, _double, base, field_width, precision, flags);
+                       str = numberf(str, end, (int)_double, base, field_width, precision, flags);
          }
 
           continue;
index 3d6488b..64d7d65 100644 (file)
 #define SPECIAL        32              /* 0x */
 #define LARGE  64              /* use 'ABCDEF' instead of 'abcdef' */
 #define REMOVEHEX      256             /* use 256 as remve 0x frim BASE 16  */
-typedef union {
-    struct {
-        unsigned int mantissal:32;
-        unsigned int mantissah:20;
-        unsigned int exponent:11;
-        unsigned int sign:1;
-    };
-    long long AsLongLong;
+typedef struct {
+    unsigned int mantissal:32;
+    unsigned int mantissah:20;
+    unsigned int exponent:11;
+    unsigned int sign:1;
 } double_t;
 
-/* We depend on this being true */
-C_ASSERT(sizeof(double_t) == sizeof(double));
-
 static
 __inline
 int
-_isinf(double_t x)
+_isinf(double __x)
 {
-       return ( x.exponent == 0x7ff  && ( x.mantissah == 0 && x.mantissal == 0 ));
+       union
+       {
+               double*   __x;
+               double_t*   x;
+       } x;
+
+       x.__x = &__x;
+       return ( x.x->exponent == 0x7ff  && ( x.x->mantissah == 0 && x.x->mantissal == 0 ));
 }
 
 static
 __inline
 int
-_isnan(double_t x)
+_isnan(double __x)
 {
-       return ( x.exponent == 0x7ff  && ( x.mantissah != 0 || x.mantissal != 0 ));
+       union
+       {
+               double*   __x;
+               double_t*   x;
+       } x;
+       x.__x = &__x;
+       return ( x.x->exponent == 0x7ff  && ( x.x->mantissah != 0 || x.x->mantissal != 0 ));
 }
 
 
@@ -172,13 +179,14 @@ number(wchar_t * buf, wchar_t * end, long long num, int base, int size, int prec
 }
 
 static wchar_t *
-numberf(wchar_t * buf, wchar_t * end, double_t num, int base, int size, int precision, int type)
+numberf(wchar_t * buf, wchar_t * end, double num, int base, int size, int precision, int type)
 {
        wchar_t c, sign, tmp[66];
        const wchar_t *digits;
        const wchar_t *small_digits = L"0123456789abcdefghijklmnopqrstuvwxyz";
        const wchar_t *large_digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        int i;
+       long long x;
 
     /* FIXME
        the float version of number is direcly copy of number
@@ -193,9 +201,9 @@ numberf(wchar_t * buf, wchar_t * end, double_t num, int base, int size, int prec
        c = (type & ZEROPAD) ? L'0' : L' ';
        sign = 0;
        if (type & SIGN) {
-               if (num.sign) {
+               if (num < 0) {
                        sign = L'-';
-                       num.sign = 0;
+                       num = -num;
                        size--;
                } else if (type & PLUS) {
                        sign = L'+';
@@ -212,11 +220,15 @@ numberf(wchar_t * buf, wchar_t * end, double_t num, int base, int size, int prec
                        size--;
        }
        i = 0;
-       if (num.AsLongLong == 0)
+       if (num == 0)
                tmp[i++] = L'0';
-       else while (num.AsLongLong != 0)
+       else while (num != 0)
        {
-               tmp[i++] = digits[do_div(&num.AsLongLong,base)];
+        x = num;
+               tmp[i++] = digits[do_div(&x,base)];
+#ifndef _M_ARM // Missing __floatdidf in CeGCC 0.55 -- GCC 4.4
+               num = x;
+#endif
     }
        if (i > precision)
                precision = i;
@@ -382,7 +394,7 @@ int __cdecl _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list ar
        const char *s;
        const wchar_t *sw;
        const wchar_t *ss;
-       double_t _double;
+       double _double;
 
        int flags;              /* flags to number() */
 
@@ -588,7 +600,7 @@ int __cdecl _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list ar
                case 'f':
                case 'g':
                case 'G':
-          _double = va_arg(args, double_t);
+          _double = (double)va_arg(args, double);
 
          if ( _isnan(_double) ) {
             ss = L"Nan";
index 828e413..a1fbc15 100644 (file)
@@ -52,13 +52,13 @@ reactos/dll/win32/comctl32        # Autosync ??
 reactos/dll/win32/comdlg32        # Autosync
 reactos/dll/win32/compstui        # Autosync
 reactos/dll/win32/credui          # Autosync
-reactos/dll/win32/crypt32         # Synced to Wine-1_1_40
+reactos/dll/win32/crypt32         # Synced to Wine-1_1_43
 reactos/dll/win32/cryptdlg        # Autosync
 reactos/dll/win32/cryptdll        # Autosync
 reactos/dll/win32/cryptnet        # Autosync
 reactos/dll/win32/cryptui         # Autosync
 reactos/dll/win32/dbghelp         # Synced to Wine-20080802
-reactos/dll/win32/dciman32        # Synced to Wine-1_0-rc2
+reactos/dll/win32/dciman32        # Synced to Wine-1_1_43
 reactos/dll/win32/dwmapi          # Autosync
 reactos/dll/win32/fusion          # Autosync
 reactos/dll/win32/gdiplus         # Autosync
@@ -113,7 +113,7 @@ reactos/dll/win32/mstask          # Autosync
 reactos/dll/win32/msvcrt20        # Autosync
 reactos/dll/win32/msvfw32         # Autosync
 reactos/dll/win32/msvidc32        # Autosync
-reactos/dll/win32/msxml3          # Synced to Wine-1_1_40
+reactos/dll/win32/msxml3          # Synced to Wine-1_1_43
 reactos/dll/win32/nddeapi         # Autosync
 reactos/dll/win32/netapi32        # Autosync
 reactos/dll/win32/ntdsapi         # Autosync
@@ -144,6 +144,8 @@ reactos/dll/win32/rsabase         # Autosync
 reactos/dll/win32/rsaenh          # Autosync
 reactos/dll/win32/sccbase         # Autosync
 reactos/dll/win32/schannel        # Autosync ??
+reactos/dll/win32/secur32         # Forked
+reactos/dll/win32/security        # Forked (different .spec)
 reactos/dll/win32/sensapi         # Autosync
 reactos/dll/win32/setupapi        # Forked at Wine-20050524
 reactos/dll/win32/shell32         # Forked at Wine-20071011
@@ -154,7 +156,7 @@ reactos/dll/win32/slbcsp          # Autosync
 reactos/dll/win32/softpub         # Autosync
 reactos/dll/win32/spoolss         # Autosync
 reactos/dll/win32/stdole2.tlb     # Autosync
-reactos/dll/win32/sti             # Autosync ??
+reactos/dll/win32/sti             # Autosync
 reactos/dll/win32/sxs             # Autosync
 reactos/dll/win32/tapi32          # Autosync
 reactos/dll/win32/traffic         # Autosync
@@ -203,7 +205,7 @@ In addition the following libs, dlls and source files are mostly based on code p
 from Winehq CVS. If you are looking to update something in these files
 check Wine current souces first as it may already be fixed.
 
-reactos/lib/uuid                  # Synced to Wine-20080114
+reactos/lib/sdk/uuid                  # Synced to Wine-1.1.42
 
 advapi32 -
   reactos/dll/win32/advapi32/crypt/*.c          # ekohl says we're not sharing this
index 5302cc6..1ed562e 100644 (file)
@@ -1,6 +1,8 @@
 <?xml version="1.0"?>
 <!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">
 <group>
+       <cdfile installbase="$(CDOUTPUT)">hosts</cdfile>
+       <installfile installbase="system32/drivers/etc">hosts</installfile>
        <cdfile installbase="$(CDOUTPUT)">services</cdfile>
        <installfile installbase="system32/drivers/etc">services</installfile>
        <if property="KDBG" value="1">
diff --git a/media/drivers/etc/hosts b/media/drivers/etc/hosts
new file mode 100644 (file)
index 0000000..f8352ba
--- /dev/null
@@ -0,0 +1,3 @@
+# ReactOS hosts file\r
+\r
+127.0.0.1 localhost\r
index bc2517d..087ab20 100644 (file)
Binary files a/media/inf/cpu.inf and b/media/inf/cpu.inf differ
index a946963..f2179ab 100644 (file)
Binary files a/media/inf/display.inf and b/media/inf/display.inf differ
index 0da85d2..445f38e 100644 (file)
Binary files a/media/inf/fdc.inf and b/media/inf/fdc.inf differ
index 0ad794c..78983c5 100644 (file)
Binary files a/media/inf/hdc.inf and b/media/inf/hdc.inf differ
index ecc9037..0ac8b68 100644 (file)
Binary files a/media/inf/machine.inf and b/media/inf/machine.inf differ
index 85f2ed9..538c3e5 100644 (file)
 
 /* FUNCTIONS *****************************************************************/
 
+BOOLEAN
+NTAPI
+CmpIsHiveAlreadyLoaded(IN HANDLE KeyHandle,
+                       IN POBJECT_ATTRIBUTES SourceFile,
+                       OUT PCMHIVE *CmHive)
+{
+    NTSTATUS Status;
+    PCM_KEY_BODY KeyBody;
+    PCMHIVE Hive;
+    BOOLEAN Loaded = FALSE;
+    PAGED_CODE();
+
+    /* Sanity check */
+    CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK();
+
+    /* Reference the handle */
+    Status = ObReferenceObjectByHandle(KeyHandle,
+                                       0,
+                                       CmpKeyObjectType,
+                                       KernelMode,
+                                       (PVOID)&KeyBody,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) return Loaded;
+
+    /* Don't touch deleted KCBs */
+    if (KeyBody->KeyControlBlock->Delete) return Loaded;
+
+    Hive = CONTAINING_RECORD(KeyBody->KeyControlBlock->KeyHive, CMHIVE, Hive);
+
+    /* Must be the root key */
+    if (!(KeyBody->KeyControlBlock->Flags & KEY_HIVE_ENTRY) ||
+        !(Hive->FileUserName.Buffer))
+    {
+        /* It isn't */
+        ObDereferenceObject(KeyBody);
+        return Loaded;
+    }
+
+    /* Now compare the name of the file */
+    if (!RtlCompareUnicodeString(&Hive->FileUserName,
+                                 SourceFile->ObjectName,
+                                 TRUE))
+    {
+        /* Same file found */
+        Loaded = TRUE;
+        *CmHive = Hive;
+        
+        /* If the hive is frozen, not sure what to do */
+        if (Hive->Frozen)
+        {
+            /* FIXME: TODO */
+            DPRINT1("ERROR: Hive is frozen\n");
+            while (TRUE);
+        }
+     }
+
+     /* Dereference and return result */
+     ObDereferenceObject(KeyBody);
+     return Loaded;
+ }
 BOOLEAN
 NTAPI
 CmpDoFlushAll(IN BOOLEAN ForceFlush)
@@ -39,16 +100,35 @@ CmpDoFlushAll(IN BOOLEAN ForceFlush)
         if (!(Hive->Hive.HiveFlags & HIVE_NOLAZYFLUSH))
         {
             /* Acquire the flusher lock */
-            ExAcquirePushLockExclusive((PVOID)&Hive->FlusherLock);
-
-            /* Do the sync */
-            Status = HvSyncHive(&Hive->Hive);
+            CmpLockHiveFlusherExclusive(Hive);
+            
+            /* Check for illegal state */
+            if ((ForceFlush) && (Hive->UseCount))
+            {
+                /* Registry needs to be locked down */
+                CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK();
+                DPRINT1("FIXME: Hive is damaged and needs fixup\n");
+                while (TRUE);
+            }
+            
+            /* Only sync if we are forced to or if it won't cause a hive shrink */
+            if ((ForceFlush) || (!HvHiveWillShrink(&Hive->Hive)))
+            {
+                /* Do the sync */
+                Status = HvSyncHive(&Hive->Hive);
 
-            /* If something failed - set the flag and continue looping*/
-            if (!NT_SUCCESS(Status)) Result = FALSE;
+                /* If something failed - set the flag and continue looping */
+                if (!NT_SUCCESS(Status)) Result = FALSE;
+            }
+            else
+            {
+                /* We won't flush if the hive might shrink */
+                Result = FALSE;
+                CmpForceForceFlush = TRUE;
+            }
 
             /* Release the flusher lock */
-            ExReleasePushLock((PVOID)&Hive->FlusherLock);
+            CmpUnlockHiveFlusher(Hive);
         }
 
         /* Try the next entry */
@@ -81,10 +161,14 @@ CmpSetValueKeyNew(IN PHHIVE Hive,
     {
         /* Then make sure it's valid and dirty it */
         ASSERT(Parent->ValueList.List != HCELL_NIL);
-        HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE);
+        if (!HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE))
+        {
+            /* Fail if we're out of space for log changes */
+            return STATUS_NO_LOG_SPACE;
+        }
     }
 
-    /* Allocate  avalue cell */
+    /* Allocate value cell */
     ValueCell = HvAllocateCell(Hive,
                                FIELD_OFFSET(CM_KEY_VALUE, Name) +
                                CmpNameSize(Hive, ValueName),
@@ -102,16 +186,33 @@ CmpSetValueKeyNew(IN PHHIVE Hive,
 
     /* Set it up and copy the name */
     CellData->u.KeyValue.Signature = CM_KEY_VALUE_SIGNATURE;
-    CellData->u.KeyValue.Flags = 0;
-    CellData->u.KeyValue.Type = Type;
-    CellData->u.KeyValue.NameLength = CmpCopyName(Hive,
-                                                  CellData->u.KeyValue.Name,
-                                                  ValueName);
+    _SEH2_TRY
+    {
+        /* This can crash since the name is coming from user-mode */
+        CellData->u.KeyValue.NameLength = CmpCopyName(Hive,
+                                                      CellData->u.KeyValue.Name,
+                                                      ValueName);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Fail */
+        DPRINT1("Invalid user data!\n");
+        HvFreeCell(Hive, ValueCell);
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
+    }
+    _SEH2_END;
+
+    /* Check for compressed name */
     if (CellData->u.KeyValue.NameLength < ValueName->Length)
     {
         /* This is a compressed name */
         CellData->u.KeyValue.Flags = VALUE_COMP_NAME;
     }
+    else
+    {
+        /* No flags to set */
+        CellData->u.KeyValue.Flags = 0;
+    }
 
     /* Check if this is a normal key */
     if (DataSize > CM_KEY_VALUE_SMALL)
@@ -140,6 +241,9 @@ CmpSetValueKeyNew(IN PHHIVE Hive,
         CellData->u.KeyValue.DataLength = DataSize + CM_KEY_VALUE_SPECIAL_SIZE;
         CellData->u.KeyValue.Data = SmallData;
     }
+    
+    /* Set the type now */
+    CellData->u.KeyValue.Type = Type;
 
     /* Add this value cell to the child list */
     Status = CmpAddValueToList(Hive,
@@ -149,7 +253,12 @@ CmpSetValueKeyNew(IN PHHIVE Hive,
                                &Parent->ValueList);
 
     /* If we failed, free the entire cell, including the data */
-    if (!NT_SUCCESS(Status)) CmpFreeValue(Hive, ValueCell);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Overwrite the status with a known one */
+        CmpFreeValue(Hive, ValueCell);
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
 
     /* Return Status */
     return Status;
@@ -170,9 +279,12 @@ CmpSetValueKeyExisting(IN PHHIVE Hive,
     PCELL_DATA CellData;
     ULONG Length;
     BOOLEAN WasSmall, IsSmall;
+    
+    /* Registry writes must be blocked */
+    CMP_ASSERT_FLUSH_LOCK(Hive);
 
     /* Mark the old child cell dirty */
-    HvMarkCellDirty(Hive, OldChild, FALSE);
+    if (!HvMarkCellDirty(Hive, OldChild, FALSE)) return STATUS_NO_LOG_SPACE;
 
     /* See if this is a small or normal key */
     WasSmall = CmpIsKeyValueSmall(&Length, Value->DataLength);
@@ -185,7 +297,7 @@ CmpSetValueKeyExisting(IN PHHIVE Hive,
     ASSERT_VALUE_BIG(Hive, DataSize);
 
     /* Mark the old value dirty */
-    CmpMarkValueDataDirty(Hive, Value);
+    if (!CmpMarkValueDataDirty(Hive, Value)) return STATUS_NO_LOG_SPACE;
 
     /* Check if we have a small key */
     if (IsSmall)
@@ -203,246 +315,507 @@ CmpSetValueKeyExisting(IN PHHIVE Hive,
         Value->Type = Type;
         return STATUS_SUCCESS;
     }
-    else
+    
+    /* We have a normal key. Was the old cell also normal and had data? */
+    if (!(WasSmall) && (Length > 0))
     {
-        /* We have a normal key. Was the old cell also normal and had data? */
-        if (!(WasSmall) && (Length > 0))
-        {
-            /* Get the current data cell and actual data inside it */
-            DataCell = Value->Data;
-            ASSERT(DataCell != HCELL_NIL);
-            CellData = HvGetCell(Hive, DataCell);
-            if (!CellData) return STATUS_INSUFFICIENT_RESOURCES;
+        /* Get the current data cell and actual data inside it */
+        DataCell = Value->Data;
+        ASSERT(DataCell != HCELL_NIL);
+        CellData = HvGetCell(Hive, DataCell);
+        if (!CellData) return STATUS_INSUFFICIENT_RESOURCES;
 
-            /* Immediately release the cell */
-            HvReleaseCell(Hive, DataCell);
+        /* Immediately release the cell */
+        HvReleaseCell(Hive, DataCell);
 
-            /* Make sure that the data cell actually has a size */
-            ASSERT(HvGetCellSize(Hive, CellData) > 0);
+        /* Make sure that the data cell actually has a size */
+        ASSERT(HvGetCellSize(Hive, CellData) > 0);
 
-            /* Check if the previous data cell could fit our new data */
-            if (DataSize <= (ULONG)(HvGetCellSize(Hive, CellData)))
-            {
-                /* Re-use it then */
-                NewCell = DataCell;
-            }
-            else
-            {
-                /* Otherwise, re-allocate the current data cell */
-                NewCell = HvReallocateCell(Hive, DataCell, DataSize);
-                if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
-            }
+        /* Check if the previous data cell could fit our new data */
+        if (DataSize <= (ULONG)(HvGetCellSize(Hive, CellData)))
+        {
+            /* Re-use it then */
+            NewCell = DataCell;
         }
         else
         {
-            /* This was a small key, or a key with no data, allocate a cell */
-            NewCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL);
+            /* Otherwise, re-allocate the current data cell */
+            NewCell = HvReallocateCell(Hive, DataCell, DataSize);
             if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
         }
+    }
+    else
+    {
+        /* This was a small key, or a key with no data, allocate a cell */
+        NewCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL);
+        if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
+    }
 
-        /* Now get the actual data for our data cell */
-        CellData = HvGetCell(Hive, NewCell);
-        if (!CellData) ASSERT(FALSE);
+    /* Now get the actual data for our data cell */
+    CellData = HvGetCell(Hive, NewCell);
+    if (!CellData) ASSERT(FALSE);
 
-        /* Release it immediately */
-        HvReleaseCell(Hive, NewCell);
+    /* Release it immediately */
+    HvReleaseCell(Hive, NewCell);
 
-        /* Copy our data into the data cell's buffer, and set up the value */
-        RtlCopyMemory(CellData, Data, DataSize);
-        Value->Data = NewCell;
-        Value->DataLength = DataSize;
-        Value->Type = Type;
+    /* Copy our data into the data cell's buffer, and set up the value */
+    RtlCopyMemory(CellData, Data, DataSize);
+    Value->Data = NewCell;
+    Value->DataLength = DataSize;
+    Value->Type = Type;
 
-        /* Return success */
-        ASSERT(HvIsCellDirty(Hive, NewCell));
-        return STATUS_SUCCESS;
-    }
+    /* Return success */
+    ASSERT(HvIsCellDirty(Hive, NewCell));
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
 NTAPI
-CmSetValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
-              IN PUNICODE_STRING ValueName,
-              IN ULONG Type,
-              IN PVOID Data,
-              IN ULONG DataLength)
+CmpQueryKeyData(IN PHHIVE Hive,
+                IN PCM_KEY_NODE Node,
+                IN KEY_INFORMATION_CLASS KeyInformationClass,
+                IN OUT PVOID KeyInformation,
+                IN ULONG Length,
+                IN OUT PULONG ResultLength)
 {
-    PHHIVE Hive;
-    PCM_KEY_NODE Parent;
-    PCM_KEY_VALUE Value = NULL;
-    HCELL_INDEX CurrentChild, Cell;
     NTSTATUS Status;
-    BOOLEAN Found, Result;
-    ULONG Count, ChildIndex, SmallData, Storage;
-    VALUE_SEARCH_RETURN_TYPE SearchResult;
+    ULONG Size, SizeLeft, MinimumSize;
+    PKEY_INFORMATION Info = (PKEY_INFORMATION)KeyInformation;
+    USHORT NameLength;
 
-    /* Acquire hive lock */
-    CmpLockRegistry();
-    CmpAcquireKcbLockShared(Kcb);
-    
-    /* Sanity check */
-    ASSERT(sizeof(ULONG) == CM_KEY_VALUE_SMALL);
-    
-    /* Don't touch deleted KCBs */
-DoAgain:
-    if (Kcb->Delete)
-    {
-        /* Fail */
-        Status = STATUS_KEY_DELETED;
-        goto Quickie;
-    }
-    
-    /* Don't let anyone mess with symlinks */
-    if ((Kcb->Flags & KEY_SYM_LINK) &&
-        ((Type != REG_LINK) ||
-         !(ValueName) ||
-         !(RtlEqualUnicodeString(&CmSymbolicLinkValueName, ValueName, TRUE))))
-    {
-        /* Invalid modification of a symlink key */
-        Status = STATUS_ACCESS_DENIED;
-        goto Quickie;
-    }
-    
-    /* Search for the value */
-    SearchResult = CmpCompareNewValueDataAgainstKCBCache(Kcb,
-                                                         ValueName,
-                                                         Type,
-                                                         Data,
-                                                         DataLength);
-    if (SearchResult == SearchNeedExclusiveLock)
+    /* Check if the value is compressed */
+    if (Node->Flags & KEY_COMP_NAME)
     {
-        /* Try again with the exclusive lock */
-        CmpConvertKcbSharedToExclusive(Kcb);
-        goto DoAgain;
+        /* Get the compressed name size */
+        NameLength = CmpCompressedNameSize(Node->Name, Node->NameLength);
     }
-    else if (SearchResult == SearchSuccess)
+    else
     {
-        /* We don't actually need to do anything! */
-        Status = STATUS_SUCCESS;
-        goto Quickie;
+        /* Get the real size */
+        NameLength = Node->NameLength;
     }
 
-    /* We need the exclusive KCB lock now */
-    if (!(CmpIsKcbLockedExclusive(Kcb)) && !(CmpTryToConvertKcbSharedToExclusive(Kcb)))
+    /* Check what kind of information is being requested */
+    switch (KeyInformationClass)
     {
-        /* Acquire exclusive lock */
-        CmpConvertKcbSharedToExclusive(Kcb);
-    }
+        /* Basic information */
+        case KeyBasicInformation:
 
-    /* Get pointer to key cell */
-    Hive = Kcb->KeyHive;
-    Cell = Kcb->KeyCell;
+            /* This is the size we need */
+            Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + NameLength;
 
-    /* Prepare to scan the key node */
-    Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
-    Count = Parent->ValueList.Count;
-    Found = FALSE;
-    if (Count > 0)
-    {
-        /* Try to find the existing name */
-        Result = CmpFindNameInList(Hive,
-                                   &Parent->ValueList,
-                                   ValueName,
-                                   &ChildIndex,
-                                   &CurrentChild);
-        if (!Result)
-        {
-            /* Fail */
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-            goto Quickie;
-        }
+            /* And this is the minimum we can work with */
+            MinimumSize = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name);
 
-        /* Check if we found something */
-        if (CurrentChild != HCELL_NIL)
-        {
-            /* Get its value */
-            Value = (PCM_KEY_VALUE)HvGetCell(Hive, CurrentChild);
-            if (!Value)
+            /* Let the caller know and assume success */
+            *ResultLength = Size;
+            Status = STATUS_SUCCESS;
+
+            /* Check if the bufer we got is too small */
+            if (Length < MinimumSize)
             {
-                /* Fail */
-                Status = STATUS_INSUFFICIENT_RESOURCES;
-                goto Quickie;
+                /* Let the caller know and fail */
+                Status = STATUS_BUFFER_TOO_SMALL;
+                break;
             }
 
-            /* Remember that we found it */
-            Found = TRUE;
-        }
-    }
-    else
-    {
-        /* No child list, we'll need to add it */
-        ChildIndex = 0;
-    }
-    
-    /* The KCB must be locked exclusive at this point */
-    ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) ||
-           (CmpTestRegistryLockExclusive() == TRUE));
-    
-    /* Mark the cell dirty */
-    HvMarkCellDirty(Hive, Cell, FALSE);
+            /* Copy the basic information */
+            Info->KeyBasicInformation.LastWriteTime = Node->LastWriteTime;
+            Info->KeyBasicInformation.TitleIndex = 0;
+            Info->KeyBasicInformation.NameLength = NameLength;
 
-    /* Get the storage type */
-    Storage = HvGetCellType(Cell);
+            /* Only the name is left */
+            SizeLeft = Length - MinimumSize;
+            Size = NameLength;
 
-    /* Check if this is small data */
-    SmallData = 0;
-    if ((DataLength <= CM_KEY_VALUE_SMALL) && (DataLength > 0))
-    {
-        /* Copy it */
-        RtlCopyMemory(&SmallData, Data, DataLength);
-    }
+            /* Check if we don't have enough space for the name */
+            if (SizeLeft < Size)
+            {
+                /* Truncate the name we'll return, and tell the caller */
+                Size = SizeLeft;
+                Status = STATUS_BUFFER_OVERFLOW;
+            }
 
-    /* Check if we didn't find a matching key */
-    if (!Found)
-    {
-        /* Call the internal routine */
-        Status = CmpSetValueKeyNew(Hive,
-                                   Parent,
-                                   ValueName,
-                                   ChildIndex,
-                                   Type,
-                                   Data,
-                                   DataLength,
-                                   Storage,
-                                   SmallData);
-    }
-    else
-    {
-        /* Call the internal routine */
-        Status = CmpSetValueKeyExisting(Hive,
-                                        CurrentChild,
-                                        Value,
-                                        Type,
-                                        Data,
-                                        DataLength,
-                                        Storage,
-                                        SmallData);
-    }
+            /* Check if this is a compressed key */
+            if (Node->Flags & KEY_COMP_NAME)
+            {
+                /* Copy the compressed name */
+                CmpCopyCompressedName(Info->KeyBasicInformation.Name,
+                                      SizeLeft,
+                                      Node->Name,
+                                      Node->NameLength);
+            }
+            else
+            {
+                /* Otherwise, copy the raw name */
+                RtlCopyMemory(Info->KeyBasicInformation.Name,
+                              Node->Name,
+                              Size);
+            }
+            break;
 
-    /* Check for success */
-    if (NT_SUCCESS(Status))
-    {
-        /* Check if the maximum value name length changed */
-        ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
-        if (Parent->MaxValueNameLen < ValueName->Length)
-        {
-            /* Set the new values */
-            Parent->MaxValueNameLen = ValueName->Length;
-            Kcb->KcbMaxValueNameLen = ValueName->Length;
-        }
-    
-        /* Check if the maximum data length changed */
-        ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
-        if (Parent->MaxValueDataLen < DataLength)
-        {
-            /* Update it */
-            Parent->MaxValueDataLen = DataLength;
-            Kcb->KcbMaxValueDataLen = Parent->MaxValueDataLen;
-        }
+        /* Node information */
+        case KeyNodeInformation:
+
+            /* Calculate the size we need */
+            Size = FIELD_OFFSET(KEY_NODE_INFORMATION, Name) +
+                   NameLength +
+                   Node->ClassLength;
+
+            /* And the minimum size we can support */
+            MinimumSize = FIELD_OFFSET(KEY_NODE_INFORMATION, Name);
+
+            /* Return the size to the caller and assume succes */
+            *ResultLength = Size;
+            Status = STATUS_SUCCESS;
+
+            /* Check if the caller's buffer is too small */
+            if (Length < MinimumSize)
+            {
+                /* Let them know, and fail */
+                Status = STATUS_BUFFER_TOO_SMALL;
+                break;
+            }
+
+            /* Copy the basic information */
+            Info->KeyNodeInformation.LastWriteTime = Node->LastWriteTime;
+            Info->KeyNodeInformation.TitleIndex = 0;
+            Info->KeyNodeInformation.ClassLength = Node->ClassLength;
+            Info->KeyNodeInformation.NameLength = NameLength;
+
+            /* Now the name is left */
+            SizeLeft = Length - MinimumSize;
+            Size = NameLength;
+
+            /* Check if the name can fit entirely */
+            if (SizeLeft < Size)
+            {
+                /* It can't, we'll have to truncate. Tell the caller */
+                Size = SizeLeft;
+                Status = STATUS_BUFFER_OVERFLOW;
+            }
+
+            /* Check if the key node name is compressed */
+            if (Node->Flags & KEY_COMP_NAME)
+            {
+                /* Copy the compressed name */
+                CmpCopyCompressedName(Info->KeyNodeInformation.Name,
+                                      SizeLeft,
+                                      Node->Name,
+                                      Node->NameLength);
+            }
+            else
+            {
+                /* It isn't, so copy the raw name */
+                RtlCopyMemory(Info->KeyNodeInformation.Name,
+                              Node->Name,
+                              Size);
+            }
+
+            /* Check if the node has a class */
+            if (Node->ClassLength > 0)
+            {
+                /* It does. We don't support these yet */
+                ASSERTMSG("Classes not supported\n", FALSE);
+            }
+            else
+            {
+                /* It doesn't, so set offset to -1, not 0! */
+                Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF;
+            }
+            break;
+
+        /* Full information requsted */
+        case KeyFullInformation:
+
+            /* This is the size we need */
+            Size = FIELD_OFFSET(KEY_FULL_INFORMATION, Class) +
+                   Node->ClassLength;
+
+            /* This is what we can work with */
+            MinimumSize = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
+
+            /* Return it to caller and assume success */
+            *ResultLength = Size;
+            Status = STATUS_SUCCESS;
+
+            /* Check if the caller's buffer is to small */
+            if (Length < MinimumSize)
+            {
+                /* Let them know and fail */
+                Status = STATUS_BUFFER_TOO_SMALL;
+                break;
+            }
+
+            /* Now copy all the basic information */
+            Info->KeyFullInformation.LastWriteTime = Node->LastWriteTime;
+            Info->KeyFullInformation.TitleIndex = 0;
+            Info->KeyFullInformation.ClassLength = Node->ClassLength;
+            Info->KeyFullInformation.SubKeys = Node->SubKeyCounts[Stable] +
+                                               Node->SubKeyCounts[Volatile];
+            Info->KeyFullInformation.Values = Node->ValueList.Count;
+            Info->KeyFullInformation.MaxNameLen = Node->MaxNameLen;
+            Info->KeyFullInformation.MaxClassLen = Node->MaxClassLen;
+            Info->KeyFullInformation.MaxValueNameLen = Node->MaxValueNameLen;
+            Info->KeyFullInformation.MaxValueDataLen = Node->MaxValueDataLen;
+
+            /* Check if we have a class */
+            if (Node->ClassLength > 0)
+            {
+                /* We do, but we currently don't support this */
+                ASSERTMSG("Classes not supported\n", FALSE);
+            }
+            else
+            {
+                /* We don't have a class, so set offset to -1, not 0! */
+                Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF;
+            }
+            break;
+
+        /* Any other class that got sent here is invalid! */
+        default:
+
+            /* Set failure code */
+            Status = STATUS_INVALID_PARAMETER;
+            break;
+    }
+
+    /* Return status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+CmSetValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
+              IN PUNICODE_STRING ValueName,
+              IN ULONG Type,
+              IN PVOID Data,
+              IN ULONG DataLength)
+{
+    PHHIVE Hive = NULL;
+    PCM_KEY_NODE Parent;
+    PCM_KEY_VALUE Value = NULL;
+    HCELL_INDEX CurrentChild, Cell;
+    NTSTATUS Status;
+    BOOLEAN Found, Result;
+    ULONG Count, ChildIndex, SmallData, Storage;
+    VALUE_SEARCH_RETURN_TYPE SearchResult;
+    BOOLEAN FirstTry = TRUE, FlusherLocked = FALSE;
+    HCELL_INDEX ParentCell = HCELL_NIL, ChildCell = HCELL_NIL;
+
+    /* Acquire hive and KCB lock */
+    CmpLockRegistry();
+    CmpAcquireKcbLockShared(Kcb);
+    
+    /* Sanity check */
+    ASSERT(sizeof(ULONG) == CM_KEY_VALUE_SMALL);
+    
+    /* Don't touch deleted KCBs */
+DoAgain:
+    if (Kcb->Delete)
+    {
+        /* Fail */
+        Status = STATUS_KEY_DELETED;
+        goto Quickie;
+    }
+    
+    /* Don't let anyone mess with symlinks */
+    if ((Kcb->Flags & KEY_SYM_LINK) &&
+        ((Type != REG_LINK) ||
+         !(ValueName) ||
+         !(RtlEqualUnicodeString(&CmSymbolicLinkValueName, ValueName, TRUE))))
+    {
+        /* Invalid modification of a symlink key */
+        Status = STATUS_ACCESS_DENIED;
+        goto Quickie;
+    }
+
+    /* Check if this is the first attempt */
+    if (FirstTry)
+    {
+        /* Search for the value in the cache */
+        SearchResult = CmpCompareNewValueDataAgainstKCBCache(Kcb,
+                                                             ValueName,
+                                                             Type,
+                                                             Data,
+                                                             DataLength);
+        if (SearchResult == SearchNeedExclusiveLock)
+        {
+            /* Try again with the exclusive lock */
+            CmpConvertKcbSharedToExclusive(Kcb);
+            goto DoAgain;
+        }
+        else if (SearchResult == SearchSuccess)
+        {
+            /* We don't actually need to do anything! */
+            Status = STATUS_SUCCESS;
+            goto Quickie;
+        }
+
+        /* We need the exclusive KCB lock now */
+        if (!(CmpIsKcbLockedExclusive(Kcb)) &&
+            !(CmpTryToConvertKcbSharedToExclusive(Kcb)))
+        {
+            /* Acquire exclusive lock */
+            CmpConvertKcbSharedToExclusive(Kcb);
+        }
+        
+        /* Cache lookup failed, so don't try it next time */
+        FirstTry = FALSE;
+        
+        /* Now grab the flush lock since the key will be modified */
+        ASSERT(FlusherLocked == FALSE);
+        CmpLockHiveFlusherShared((PCMHIVE)Kcb->KeyHive);
+        FlusherLocked = TRUE;
+        goto DoAgain;
+    }
+    else
+    {
+        /* Get pointer to key cell */
+        Hive = Kcb->KeyHive;
+        Cell = Kcb->KeyCell;
+
+        /* Get the parent */
+        Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
+        ASSERT(Parent);
+        ParentCell = Cell;
+        
+        /* Prepare to scan the key node */
+        Count = Parent->ValueList.Count;
+        Found = FALSE;
+        if (Count > 0)
+        {
+            /* Try to find the existing name */
+            Result = CmpFindNameInList(Hive,
+                                       &Parent->ValueList,
+                                       ValueName,
+                                       &ChildIndex,
+                                       &CurrentChild);
+            if (!Result)
+            {
+                /* Fail */
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                goto Quickie;
+            }
+
+            /* Check if we found something */
+            if (CurrentChild != HCELL_NIL)
+            {
+                /* Release existing child */
+                if (ChildCell != HCELL_NIL)
+                {
+                    HvReleaseCell(Hive, ChildCell);
+                    ChildCell = HCELL_NIL;
+                }
+                
+                /* Get its value */
+                Value = (PCM_KEY_VALUE)HvGetCell(Hive, CurrentChild);
+                if (!Value)
+                {
+                    /* Fail */
+                    Status = STATUS_INSUFFICIENT_RESOURCES;
+                    goto Quickie;
+                }
+
+                /* Remember that we found it */
+                ChildCell = CurrentChild;
+                Found = TRUE;
+            }
+        }
+        else
+        {
+            /* No child list, we'll need to add it */
+            ChildIndex = 0;
+        }
+    }
+    
+    /* Should only get here on the second pass */
+    ASSERT(FirstTry == FALSE);
+    
+    /* The KCB must be locked exclusive at this point */
+    CMP_ASSERT_KCB_LOCK(Kcb);
+    
+    /* Mark the cell dirty */
+    if (!HvMarkCellDirty(Hive, Cell, FALSE))
+    {
+        /* Not enough log space, fail */
+        Status = STATUS_NO_LOG_SPACE;
+        goto Quickie;
+    }
+
+    /* Get the storage type */
+    Storage = HvGetCellType(Cell);
+
+    /* Check if this is small data */
+    SmallData = 0;
+    if ((DataLength <= CM_KEY_VALUE_SMALL) && (DataLength > 0))
+    {
+        /* Need SEH because user data may be invalid */
+        _SEH2_TRY
+        {
+            /* Copy it */
+            RtlCopyMemory(&SmallData, Data, DataLength);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Return failure code */
+            Status = _SEH2_GetExceptionCode();
+            _SEH2_YIELD(goto Quickie);
+        }
+        _SEH2_END;
+    }
+
+    /* Check if we didn't find a matching key */
+    if (!Found)
+    {
+        /* Call the internal routine */
+        Status = CmpSetValueKeyNew(Hive,
+                                   Parent,
+                                   ValueName,
+                                   ChildIndex,
+                                   Type,
+                                   Data,
+                                   DataLength,
+                                   Storage,
+                                   SmallData);
+    }
+    else
+    {
+        /* Call the internal routine */
+        Status = CmpSetValueKeyExisting(Hive,
+                                        CurrentChild,
+                                        Value,
+                                        Type,
+                                        Data,
+                                        DataLength,
+                                        Storage,
+                                        SmallData);
+    }
+
+    /* Check for success */
+    if (NT_SUCCESS(Status))
+    {
+        /* Check if the maximum value name length changed */
+        ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
+        if (Parent->MaxValueNameLen < ValueName->Length)
+        {
+            /* Set the new values */
+            Parent->MaxValueNameLen = ValueName->Length;
+            Kcb->KcbMaxValueNameLen = ValueName->Length;
+        }
+    
+        /* Check if the maximum data length changed */
+        ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
+        if (Parent->MaxValueDataLen < DataLength)
+        {
+            /* Update it */
+            Parent->MaxValueDataLen = DataLength;
+            Kcb->KcbMaxValueDataLen = Parent->MaxValueDataLen;
+        }
         
         /* Save the write time */
         KeQuerySystemTime(&Parent->LastWriteTime);
-        KeQuerySystemTime(&Kcb->KcbLastWriteTime);
+        Kcb->KcbLastWriteTime = Parent->LastWriteTime;
         
         /* Check if the cell is cached */
         if ((Found) && (CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)))
@@ -463,10 +836,21 @@ DoAgain:
             Kcb->ValueCache.Count = Parent->ValueList.Count;
             Kcb->ValueCache.ValueList = Parent->ValueList.List;
         }
+        
+        /* Notify registered callbacks */
+        CmpReportNotify(Kcb,
+                        Hive,
+                        Kcb->KeyCell,
+                        REG_NOTIFY_CHANGE_LAST_SET);
     }
     
+    /* Release the cells */
 Quickie:
+    if ((ParentCell != HCELL_NIL) && (Hive)) HvReleaseCell(Hive, ParentCell);
+    if ((ChildCell != HCELL_NIL) && (Hive)) HvReleaseCell(Hive, ChildCell);
+
     /* Release the locks */
+    if (FlusherLocked) CmpUnlockHiveFlusher((PCMHIVE)Hive);
     CmpReleaseKcbLock(Kcb);
     CmpUnlockRegistry();
     return Status;
@@ -504,15 +888,13 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
     /* Get the hive and the cell index */
     Hive = Kcb->KeyHive;
     Cell = Kcb->KeyCell;
+    
+    /* Lock flushes */
+    CmpLockHiveFlusherShared((PCMHIVE)Hive);
 
     /* Get the parent key node */
     Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
-    if (!Parent)
-    {
-        /* Fail */
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto Quickie;
-    }
+    ASSERT(Parent);
 
     /* Get the value list and check if it has any entries */
     ChildList = &Parent->ValueList;
@@ -535,16 +917,26 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
         if (ChildCell == HCELL_NIL) goto Quickie;
 
         /* We found the value, mark all relevant cells dirty */
-        HvMarkCellDirty(Hive, Cell, FALSE);
-        HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE);
-        HvMarkCellDirty(Hive, ChildCell, FALSE);
+        if (!((HvMarkCellDirty(Hive, Cell, FALSE)) &&
+              (HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE)) &&
+              (HvMarkCellDirty(Hive, ChildCell, FALSE))))
+        {
+            /* Not enough log space, fail */
+            Status = STATUS_NO_LOG_SPACE;
+            goto Quickie;
+        }
 
         /* Get the key value */
         Value = (PCM_KEY_VALUE)HvGetCell(Hive,ChildCell);
-        if (!Value) ASSERT(FALSE);
+        ASSERT(Value);
 
         /* Mark it and all related data as dirty */
-        CmpMarkValueDataDirty(Hive, Value);
+        if (!CmpMarkValueDataDirty(Hive, Value))
+        {
+            /* Not enough log space, fail */
+            Status = STATUS_NO_LOG_SPACE;
+            goto Quickie;
+        }
 
         /* Ssanity checks */
         ASSERT(HvIsCellDirty(Hive, Parent->ValueList.List));
@@ -552,7 +944,12 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
 
         /* Remove the value from the child list */
         Status = CmpRemoveValueFromList(Hive, ChildIndex, ChildList);
-        if(!NT_SUCCESS(Status)) goto Quickie;
+        if (!NT_SUCCESS(Status))
+        {
+            /* Set known error */
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto Quickie;
+        }
 
         /* Remove the value and its data itself */
         if (!CmpFreeValue(Hive, ChildCell))
@@ -564,7 +961,7 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
 
         /* Set the last write time */
         KeQuerySystemTime(&Parent->LastWriteTime);
-        KeQuerySystemTime(&Kcb->KcbLastWriteTime);
+        Kcb->KcbLastWriteTime = Parent->LastWriteTime;
 
         /* Sanity check */
         ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
@@ -591,6 +988,9 @@ CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
         /* Set the value cache */
         Kcb->ValueCache.Count = ChildList->Count;
         Kcb->ValueCache.ValueList = ChildList->List;
+        
+        /* Notify registered callbacks */
+        CmpReportNotify(Kcb, Hive, Cell, REG_NOTIFY_CHANGE_LAST_SET);
 
         /* Change default Status to success */
         Status = STATUS_SUCCESS;
@@ -609,6 +1009,7 @@ Quickie:
     }
 
     /* Release locks */
+    CmpUnlockHiveFlusher((PCMHIVE)Hive);
     CmpReleaseKcbLock(Kcb);
     CmpUnlockRegistry();
     return Status;
@@ -683,22 +1084,38 @@ DoAgain:
         /* Sanity check */
         ASSERT(ValueData != NULL);
 
-        /* Query the information requested */
-        Result = CmpQueryKeyValueData(Kcb,
-                                      CachedValue,
-                                      ValueData,
-                                      ValueCached,
-                                      KeyValueInformationClass,
-                                      KeyValueInformation,
-                                      Length,
-                                      ResultLength,
-                                      &Status);
-        if (Result == SearchNeedExclusiveLock)
-        {            
-            /* Try with exclusive KCB lock */
-            CmpConvertKcbSharedToExclusive(Kcb);
-            goto DoAgain;
+        /* User data, protect against exceptions */
+        _SEH2_TRY
+        {
+            /* Query the information requested */
+            Result = CmpQueryKeyValueData(Kcb,
+                                          CachedValue,
+                                          ValueData,
+                                          ValueCached,
+                                          KeyValueInformationClass,
+                                          KeyValueInformation,
+                                          Length,
+                                          ResultLength,
+                                          &Status);
+            if (Result == SearchNeedExclusiveLock)
+            {            
+                /* Release the value cell */
+                if (CellToRelease != HCELL_NIL)
+                {
+                    HvReleaseCell(Hive, CellToRelease);
+                    CellToRelease = HCELL_NIL;
+                }
+                
+                /* Try with exclusive KCB lock */
+                CmpConvertKcbSharedToExclusive(Kcb);
+                goto DoAgain;
+            }
         }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            Status = _SEH2_GetExceptionCode();
+        }
+        _SEH2_END;
     }
     else
     {
@@ -735,344 +1152,154 @@ CmEnumerateValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
     PCM_KEY_VALUE ValueData = NULL;
     PAGED_CODE();
 
-    /* Acquire hive lock */
-    CmpLockRegistry();
-    
-    /* Lock the KCB shared */
-    CmpAcquireKcbLockShared(Kcb);
-
-    /* Don't touch deleted keys */
-DoAgain:
-    if (Kcb->Delete)
-    {
-        /* Undo everything */
-        CmpReleaseKcbLock(Kcb);
-        CmpUnlockRegistry();
-        return STATUS_KEY_DELETED;
-    }
-
-    /* Get the hive and parent */
-    Hive = Kcb->KeyHive;
-    Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
-    if (!Parent)
-    {
-        /* Fail */
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto Quickie;
-    }
-
-    /* Make sure the index is valid */
-    //if (Index >= Kcb->ValueCache.Count)
-    if (Index >= Parent->ValueList.Count)
-    {
-        /* Release the cell and fail */
-        HvReleaseCell(Hive, Kcb->KeyCell);
-        Status = STATUS_NO_MORE_ENTRIES;
-        goto Quickie;
-    }
-    
-    /* We don't deal with this yet */
-    if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
-    {
-        /* Shouldn't happen */
-        ASSERT(FALSE);
-    }
-
-    /* Find the value list */
-    Result = CmpGetValueListFromCache(Kcb,
-                                      &CellData,
-                                      &IndexIsCached,
-                                      &CellToRelease);
-    if (Result == SearchNeedExclusiveLock)
-    {
-        /* Check if we need an exclusive lock */
-        ASSERT(CellToRelease == HCELL_NIL);
-        ASSERT(ValueData == NULL);
-        
-        /* Try with exclusive KCB lock */
-        CmpConvertKcbSharedToExclusive(Kcb);
-        goto DoAgain;
-    }
-    else if (Result != SearchSuccess)
-    {
-        /* Sanity check */
-        ASSERT(CellData == NULL);
-
-        /* Release the cell and fail */
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto Quickie;
-    }
-
-    /* Now get the key value */
-    Result = CmpGetValueKeyFromCache(Kcb,
-                                     CellData,
-                                     Index,
-                                     &CachedValue,
-                                     &ValueData,
-                                     IndexIsCached,
-                                     &ValueIsCached,
-                                     &CellToRelease2);
-    if (Result == SearchNeedExclusiveLock)
-    {
-        /* Try with exclusive KCB lock */
-        CmpConvertKcbSharedToExclusive(Kcb);
-        goto DoAgain;
-    }
-    else if (Result != SearchSuccess)
-    {
-        /* Sanity check */
-        ASSERT(ValueData == NULL);
-
-        /* Release the cells and fail */
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto Quickie;
-    }
-
-    /* Query the information requested */
-    Result = CmpQueryKeyValueData(Kcb,
-                                  CachedValue,
-                                  ValueData,
-                                  ValueIsCached,
-                                  KeyValueInformationClass,
-                                  KeyValueInformation,
-                                  Length,
-                                  ResultLength,
-                                  &Status);
-    if (Result == SearchNeedExclusiveLock)
-    {
-        /* Try with exclusive KCB lock */
-        CmpConvertKcbSharedToExclusive(Kcb);
-        goto DoAgain;
-    }
-
-Quickie:
-    /* If we have a cell to release, do so */
-    if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
-
-    /* Release the parent cell */
-    HvReleaseCell(Hive, Kcb->KeyCell);
-
-    /* If we have a cell to release, do so */
-    if (CellToRelease2 != HCELL_NIL) HvReleaseCell(Hive, CellToRelease2);
-
-    /* Release locks */
-    CmpReleaseKcbLock(Kcb);
-    CmpUnlockRegistry();
-    return Status;
-}
-
-NTSTATUS
-NTAPI
-CmpQueryKeyData(IN PHHIVE Hive,
-                IN PCM_KEY_NODE Node,
-                IN KEY_INFORMATION_CLASS KeyInformationClass,
-                IN OUT PVOID KeyInformation,
-                IN ULONG Length,
-                IN OUT PULONG ResultLength)
-{
-    NTSTATUS Status;
-    ULONG Size, SizeLeft, MinimumSize;
-    PKEY_INFORMATION Info = (PKEY_INFORMATION)KeyInformation;
-    USHORT NameLength;
-
-    /* Check if the value is compressed */
-    if (Node->Flags & KEY_COMP_NAME)
-    {
-        /* Get the compressed name size */
-        NameLength = CmpCompressedNameSize(Node->Name, Node->NameLength);
-    }
-    else
-    {
-        /* Get the real size */
-        NameLength = Node->NameLength;
-    }
-
-    /* Check what kind of information is being requested */
-    switch (KeyInformationClass)
-    {
-        /* Basic information */
-        case KeyBasicInformation:
-
-            /* This is the size we need */
-            Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + NameLength;
-
-            /* And this is the minimum we can work with */
-            MinimumSize = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name);
-
-            /* Let the caller know and assume success */
-            *ResultLength = Size;
-            Status = STATUS_SUCCESS;
-
-            /* Check if the bufer we got is too small */
-            if (Length < MinimumSize)
-            {
-                /* Let the caller know and fail */
-                Status = STATUS_BUFFER_TOO_SMALL;
-                break;
-            }
-
-            /* Copy the basic information */
-            Info->KeyBasicInformation.LastWriteTime = Node->LastWriteTime;
-            Info->KeyBasicInformation.TitleIndex = 0;
-            Info->KeyBasicInformation.NameLength = NameLength;
-
-            /* Only the name is left */
-            SizeLeft = Length - MinimumSize;
-            Size = NameLength;
-
-            /* Check if we don't have enough space for the name */
-            if (SizeLeft < Size)
-            {
-                /* Truncate the name we'll return, and tell the caller */
-                Size = SizeLeft;
-                Status = STATUS_BUFFER_OVERFLOW;
-            }
-
-            /* Check if this is a compressed key */
-            if (Node->Flags & KEY_COMP_NAME)
-            {
-                /* Copy the compressed name */
-                CmpCopyCompressedName(Info->KeyBasicInformation.Name,
-                                      SizeLeft,
-                                      Node->Name,
-                                      Node->NameLength);
-            }
-            else
-            {
-                /* Otherwise, copy the raw name */
-                RtlCopyMemory(Info->KeyBasicInformation.Name,
-                              Node->Name,
-                              Size);
-            }
-            break;
-
-        /* Node information */
-        case KeyNodeInformation:
-
-            /* Calculate the size we need */
-            Size = FIELD_OFFSET(KEY_NODE_INFORMATION, Name) +
-                   NameLength +
-                   Node->ClassLength;
-
-            /* And the minimum size we can support */
-            MinimumSize = FIELD_OFFSET(KEY_NODE_INFORMATION, Name);
-
-            /* Return the size to the caller and assume succes */
-            *ResultLength = Size;
-            Status = STATUS_SUCCESS;
-
-            /* Check if the caller's buffer is too small */
-            if (Length < MinimumSize)
-            {
-                /* Let them know, and fail */
-                Status = STATUS_BUFFER_TOO_SMALL;
-                break;
-            }
-
-            /* Copy the basic information */
-            Info->KeyNodeInformation.LastWriteTime = Node->LastWriteTime;
-            Info->KeyNodeInformation.TitleIndex = 0;
-            Info->KeyNodeInformation.ClassLength = Node->ClassLength;
-            Info->KeyNodeInformation.NameLength = NameLength;
-
-            /* Now the name is left */
-            SizeLeft = Length - MinimumSize;
-            Size = NameLength;
-
-            /* Check if the name can fit entirely */
-            if (SizeLeft < Size)
-            {
-                /* It can't, we'll have to truncate. Tell the caller */
-                Size = SizeLeft;
-                Status = STATUS_BUFFER_OVERFLOW;
-            }
-
-            /* Check if the key node name is compressed */
-            if (Node->Flags & KEY_COMP_NAME)
-            {
-                /* Copy the compressed name */
-                CmpCopyCompressedName(Info->KeyNodeInformation.Name,
-                                      SizeLeft,
-                                      Node->Name,
-                                      Node->NameLength);
-            }
-            else
-            {
-                /* It isn't, so copy the raw name */
-                RtlCopyMemory(Info->KeyNodeInformation.Name,
-                              Node->Name,
-                              Size);
-            }
+    /* Acquire hive lock */
+    CmpLockRegistry();
+    
+    /* Lock the KCB shared */
+    CmpAcquireKcbLockShared(Kcb);
 
-            /* Check if the node has a class */
-            if (Node->ClassLength > 0)
-            {
-                /* It does. We don't support these yet */
-                ASSERTMSG("Classes not supported\n", FALSE);
-            }
-            else
-            {
-                /* It doesn't, so set offset to -1, not 0! */
-                Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF;
-            }
-            break;
+    /* Don't touch deleted keys */
+DoAgain:
+    if (Kcb->Delete)
+    {
+        /* Undo everything */
+        CmpReleaseKcbLock(Kcb);
+        CmpUnlockRegistry();
+        return STATUS_KEY_DELETED;
+    }
 
-        /* Full information requsted */
-        case KeyFullInformation:
+    /* Get the hive and parent */
+    Hive = Kcb->KeyHive;
+    Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
+    ASSERT(Parent);
 
-            /* This is the size we need */
-            Size = FIELD_OFFSET(KEY_FULL_INFORMATION, Class) +
-                   Node->ClassLength;
+    /* FIXME: Lack of cache? */
+    if (Kcb->ValueCache.Count != Parent->ValueList.Count)
+    {
+        DPRINT1("HACK: Overriding value cache count\n");
+        Kcb->ValueCache.Count = Parent->ValueList.Count;
+    }
 
-            /* This is what we can work with */
-            MinimumSize = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
+    /* Make sure the index is valid */    
+    if (Index >= Kcb->ValueCache.Count)
+    {
+        /* Release the cell and fail */
+        HvReleaseCell(Hive, Kcb->KeyCell);
+        Status = STATUS_NO_MORE_ENTRIES;
+        goto Quickie;
+    }
+    
+    /* We don't deal with this yet */
+    if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
+    {
+        /* Shouldn't happen */
+        ASSERT(FALSE);
+    }
 
-            /* Return it to caller and assume success */
-            *ResultLength = Size;
-            Status = STATUS_SUCCESS;
+    /* Find the value list */
+    Result = CmpGetValueListFromCache(Kcb,
+                                      &CellData,
+                                      &IndexIsCached,
+                                      &CellToRelease);
+    if (Result == SearchNeedExclusiveLock)
+    {
+        /* Check if we need an exclusive lock */
+        ASSERT(CellToRelease == HCELL_NIL);
+        HvReleaseCell(Hive, Kcb->KeyCell);
+        
+        /* Try with exclusive KCB lock */
+        CmpConvertKcbSharedToExclusive(Kcb);
+        goto DoAgain;
+    }
+    else if (Result != SearchSuccess)
+    {
+        /* Sanity check */
+        ASSERT(CellData == NULL);
 
-            /* Check if the caller's buffer is to small */
-            if (Length < MinimumSize)
-            {
-                /* Let them know and fail */
-                Status = STATUS_BUFFER_TOO_SMALL;
-                break;
-            }
+        /* Release the cell and fail */
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto Quickie;
+    }
 
-            /* Now copy all the basic information */
-            Info->KeyFullInformation.LastWriteTime = Node->LastWriteTime;
-            Info->KeyFullInformation.TitleIndex = 0;
-            Info->KeyFullInformation.ClassLength = Node->ClassLength;
-            Info->KeyFullInformation.SubKeys = Node->SubKeyCounts[Stable] +
-                                               Node->SubKeyCounts[Volatile];
-            Info->KeyFullInformation.Values = Node->ValueList.Count;
-            Info->KeyFullInformation.MaxNameLen = Node->MaxNameLen;
-            Info->KeyFullInformation.MaxClassLen = Node->MaxClassLen;
-            Info->KeyFullInformation.MaxValueNameLen = Node->MaxValueNameLen;
-            Info->KeyFullInformation.MaxValueDataLen = Node->MaxValueDataLen;
+    /* Now get the key value */
+    Result = CmpGetValueKeyFromCache(Kcb,
+                                     CellData,
+                                     Index,
+                                     &CachedValue,
+                                     &ValueData,
+                                     IndexIsCached,
+                                     &ValueIsCached,
+                                     &CellToRelease2);
+    if (Result == SearchNeedExclusiveLock)
+    {
+        /* Cleanup state */
+        ASSERT(CellToRelease2 == HCELL_NIL);
+        if (CellToRelease)
+        {
+            HvReleaseCell(Hive, CellToRelease);
+            CellToRelease = HCELL_NIL;
+        }
+        HvReleaseCell(Hive, Kcb->KeyCell);
 
-            /* Check if we have a class */
-            if (Node->ClassLength > 0)
-            {
-                /* We do, but we currently don't support this */
-                ASSERTMSG("Classes not supported\n", FALSE);
-            }
-            else
-            {
-                /* We don't have a class, so set offset to -1, not 0! */
-                Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF;
-            }
-            break;
+        /* Try with exclusive KCB lock */
+        CmpConvertKcbSharedToExclusive(Kcb);
+        goto DoAgain;
+    }
+    else if (Result != SearchSuccess)
+    {
+        /* Sanity check */
+        ASSERT(ValueData == NULL);
 
-        /* Any other class that got sent here is invalid! */
-        default:
+        /* Release the cells and fail */
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto Quickie;
+    }
+    
+    /* User data, need SEH */
+    _SEH2_TRY
+    {
+        /* Query the information requested */
+        Result = CmpQueryKeyValueData(Kcb,
+                                      CachedValue,
+                                      ValueData,
+                                      ValueIsCached,
+                                      KeyValueInformationClass,
+                                      KeyValueInformation,
+                                      Length,
+                                      ResultLength,
+                                      &Status);
+        if (Result == SearchNeedExclusiveLock)
+        {
+            /* Cleanup state */
+            if (CellToRelease2) HvReleaseCell(Hive, CellToRelease2);
+            HvReleaseCell(Hive, Kcb->KeyCell);
+            if (CellToRelease) HvReleaseCell(Hive, CellToRelease);
 
-            /* Set failure code */
-            Status = STATUS_INVALID_PARAMETER;
-            break;
+            /* Try with exclusive KCB lock */
+            CmpConvertKcbSharedToExclusive(Kcb);
+            goto DoAgain;
+        }
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Get exception code */
+        Status = _SEH2_GetExceptionCode();
     }
+    _SEH2_END;
 
-    /* Return status */
+Quickie:
+    /* If we have a cell to release, do so */
+    if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
+
+    /* Release the parent cell */
+    HvReleaseCell(Hive, Kcb->KeyCell);
+
+    /* If we have a cell to release, do so */
+    if (CellToRelease2 != HCELL_NIL) HvReleaseCell(Hive, CellToRelease2);
+
+    /* Release locks */
+    CmpReleaseKcbLock(Kcb);
+    CmpUnlockRegistry();
     return Status;
 }
 
@@ -1087,6 +1314,7 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
     NTSTATUS Status;
     PHHIVE Hive;
     PCM_KEY_NODE Parent;
+    HV_TRACK_CELL_REF CellReferences = {0};
 
     /* Acquire hive lock */
     CmpLockRegistry();
@@ -1094,16 +1322,6 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
     /* Lock KCB shared */
     CmpAcquireKcbLockShared(Kcb);
 
-    /* Get the hive and parent */
-    Hive = Kcb->KeyHive;
-    Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
-    if (!Parent)
-    {
-        /* Fail */
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto Quickie;
-    }
-    
     /* Don't touch deleted keys */
     if (Kcb->Delete)
     {
@@ -1120,13 +1338,27 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
         case KeyBasicInformation:
         case KeyNodeInformation:
 
-            /* Call the internal API */
-            Status = CmpQueryKeyData(Hive,
-                                     Parent,
-                                     KeyInformationClass,
-                                     KeyInformation,
-                                     Length,
-                                     ResultLength);
+            /* Get the hive and parent */
+            Hive = Kcb->KeyHive;
+            Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
+            ASSERT(Parent);
+            
+            /* Track cell references */
+            if (!HvTrackCellRef(&CellReferences, Hive, Kcb->KeyCell))
+            {
+                /* Not enough memory to track references */
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+            }
+            else
+            {
+                /* Call the internal API */
+                Status = CmpQueryKeyData(Hive,
+                                         Parent,
+                                         KeyInformationClass,
+                                         KeyInformation,
+                                         Length,
+                                         ResultLength);
+            }
             break;
 
         /* Unsupported classes for now */
@@ -1149,6 +1381,9 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
     }
 
 Quickie:
+    /* Release references */
+    HvReleaseFreeCellRefArray(&CellReferences);
+
     /* Release locks */
     CmpReleaseKcbLock(Kcb);
     CmpUnlockRegistry();
@@ -1168,6 +1403,7 @@ CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
     PHHIVE Hive;
     PCM_KEY_NODE Parent, Child;
     HCELL_INDEX ChildCell;
+    HV_TRACK_CELL_REF CellReferences = {0};
 
     /* Acquire hive lock */
     CmpLockRegistry();
@@ -1179,20 +1415,14 @@ CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
     if (Kcb->Delete)
     {
         /* Undo everything */
-        CmpReleaseKcbLock(Kcb);
-        CmpUnlockRegistry();
-        return STATUS_KEY_DELETED;
+        Status = STATUS_KEY_DELETED;
+        goto Quickie;
     }
 
     /* Get the hive and parent */
     Hive = Kcb->KeyHive;
     Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
-    if (!Parent)
-    {
-        /* Fail */
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto Quickie;
-    }
+    ASSERT(Parent);
 
     /* Get the child cell */
     ChildCell = CmpFindSubKeyByNumber(Hive, Parent, Index);
@@ -1210,22 +1440,39 @@ CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
 
     /* Now get the actual child node */
     Child = (PCM_KEY_NODE)HvGetCell(Hive, ChildCell);
-    if (!Child)
+    ASSERT(Child);
+    
+    /* Track references */
+    if (!HvTrackCellRef(&CellReferences, Hive, ChildCell))
     {
-        /* Fail */
+        /* Can't allocate memory for tracking */
         Status = STATUS_INSUFFICIENT_RESOURCES;
         goto Quickie;
     }
 
-    /* Query the data requested */
-    Status = CmpQueryKeyData(Hive,
-                             Child,
-                             KeyInformationClass,
-                             KeyInformation,
-                             Length,
-                             ResultLength);
+    /* Data can be user-mode, use SEH */
+    _SEH2_TRY
+    {
+        /* Query the data requested */
+        Status = CmpQueryKeyData(Hive,
+                                 Child,
+                                 KeyInformationClass,
+                                 KeyInformation,
+                                 Length,
+                                 ResultLength);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Fail with exception code */
+        Status = _SEH2_GetExceptionCode();
+        _SEH2_YIELD(goto Quickie);
+    }
+    _SEH2_END;
 
 Quickie:
+    /* Release references */
+    HvReleaseFreeCellRefArray(&CellReferences);
+
     /* Release locks */
     CmpReleaseKcbLock(Kcb);
     CmpUnlockRegistry();
@@ -1271,14 +1518,12 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
     Hive = Kcb->KeyHive;
     Cell = Kcb->KeyCell;
     
+    /* Lock flushes */
+    CmpLockHiveFlusherShared((PCMHIVE)Hive);
+    
     /* Get the key node */
     Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
-    if (!Node)
-    {
-        /* Fail */
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto Quickie;
-    }
+    ASSERT(Node);
    
     /* Sanity check */
     ASSERT(Node->Flags == Kcb->Flags);
@@ -1287,11 +1532,17 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
     if (!(Node->SubKeyCounts[Stable] + Node->SubKeyCounts[Volatile]) &&
         !(Node->Flags & KEY_NO_DELETE))
     {
+        /* Send notification to registered callbacks */
+        CmpReportNotify(Kcb, Hive, Cell, REG_NOTIFY_CHANGE_NAME);
+        
         /* Get the parent and free the cell */
         ParentCell = Node->Parent;
         Status = CmpFreeKeyByCell(Hive, Cell, TRUE);
         if (NT_SUCCESS(Status))
         {
+            /* Flush any notifications */
+            CmpFlushNotifiesOnKeyBodyList(Kcb, FALSE);
+            
             /* Clean up information we have on the subkey */
             CmpCleanUpSubKeyInfo(Kcb->ParentKcb);
 
@@ -1327,10 +1578,12 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody)
         Status = STATUS_CANNOT_DELETE;
     }
     
-Quickie:
     /* Release the cell */
     HvReleaseCell(Hive, Cell);
-    
+
+    /* Release flush lock */
+    CmpUnlockHiveFlusher((PCMHIVE)Hive);
+
     /* Release the KCB locks */
 Quickie2:
     CmpReleaseTwoKcbLockByKey(Kcb->ConvKey, Kcb->ParentKcb->ConvKey);
@@ -1364,12 +1617,36 @@ CmFlushKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
     }
     else
     {
+        /* Don't touch the hive */
+        CmpLockHiveFlusherExclusive(CmHive);
+        ASSERT(CmHive->ViewLock);
+        KeAcquireGuardedMutex(CmHive->ViewLock);
+        CmHive->ViewLockOwner = KeGetCurrentThread();
+        
+        /* Will the hive shrink? */
+        if (HvHiveWillShrink(Hive))
+        {
+            /* I don't believe the current Hv does shrinking */
+            ASSERT(FALSE);
+        }
+        else
+        {
+            /* Now we can release views */
+            ASSERT(CmHive->ViewLock);
+            CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK_OR_LOADING(CmHive);
+            ASSERT(KeGetCurrentThread() == CmHive->ViewLockOwner);
+            KeReleaseGuardedMutex(CmHive->ViewLock);
+        }
+        
         /* Flush only this hive */
         if (!HvSyncHive(Hive))
         {
             /* Fail */
             Status = STATUS_REGISTRY_IO_FAILED;
         }
+        
+        /* Release the flush lock */
+        CmpUnlockHiveFlusher((PCMHIVE)Hive);
     }
 
     /* Return the status */
@@ -1387,8 +1664,9 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
     SECURITY_CLIENT_CONTEXT ClientSecurityContext;
     HANDLE KeyHandle;
     BOOLEAN Allocate = TRUE;
-    PCMHIVE CmHive;
+    PCMHIVE CmHive, LoadedHive;
     NTSTATUS Status;
+    CM_PARSE_CONTEXT ParseContext;
     
     /* Check if we have a trust key */
     if (KeyBody)
@@ -1415,9 +1693,21 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
     }
     
     /* Open the target key */
+#if 0
     Status = ZwOpenKey(&KeyHandle, KEY_READ, TargetKey);
+#else
+    RtlZeroMemory(&ParseContext, sizeof(ParseContext));
+    ParseContext.CreateOperation = FALSE;
+    Status = ObOpenObjectByName(TargetKey,
+                                CmpKeyObjectType,
+                                KernelMode,
+                                NULL,
+                                KEY_READ,
+                                &ParseContext,
+                                &KeyHandle);
+#endif
     if (!NT_SUCCESS(Status)) KeyHandle = NULL;
-    
+
     /* Open the hive */
     Status = CmpCmdHiveOpen(SourceFile,
                             &ClientSecurityContext,
@@ -1437,21 +1727,29 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
             /* Lock the registry */
             CmpLockRegistryExclusive();
             
-            /* FIXME: Check if we are already loaded */
-            
+            /* Check if we are already loaded */
+            if (CmpIsHiveAlreadyLoaded(KeyHandle, SourceFile, &LoadedHive))
+            {
+                /* That's okay then */
+                ASSERT(LoadedHive);
+                Status = STATUS_SUCCESS;
+            }
+
             /* Release the registry */
             CmpUnlockRegistry();
         }
         
         /* Close the key handle if we had one */
         if (KeyHandle) ZwClose(KeyHandle);
-        DPRINT1("Failed: %lx\n", Status);
         return Status;
     }
     
     /* Lock the registry shared */
     CmpLockRegistry();
     
+    /* Lock loading */
+    ExAcquirePushLockExclusive(&CmpLoadHiveLock);
+    
     /* Lock the hive to this thread */
     CmHive->Hive.HiveFlags |= HIVE_IS_UNLOADING;
     CmHive->CreatorOwner = KeGetCurrentThread();
@@ -1467,23 +1765,37 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
                                  TargetKey->SecurityDescriptor);
     if (NT_SUCCESS(Status))
     {
-        /* FIXME: Add to HiveList key */
+        /* Add to HiveList key */
+        CmpAddToHiveFileList(CmHive);
         
         /* Sync the hive if necessary */
         if (Allocate)
         {
-            /* Sync it */
+            /* Sync it under the flusher lock */
+            CmpLockHiveFlusherExclusive(CmHive);
             HvSyncHive(&CmHive->Hive);
+            CmpUnlockHiveFlusher(CmHive);
         }
         
         /* Release the hive */
         CmHive->Hive.HiveFlags &= ~HIVE_IS_UNLOADING;
         CmHive->CreatorOwner = NULL;
+        
+        /* Allow loads */
+        ExReleasePushLock(&CmpLoadHiveLock);
     }
     else
     {
         /* FIXME: TODO */
-        
+        ASSERT(FALSE);
+    }
+    
+    /* Is this first profile load? */
+    if (!(CmpProfileLoaded) && !(CmpWasSetupBoot))
+    {
+        /* User is now logged on, set quotas */
+        CmpProfileLoaded = TRUE;
+        CmpSetGlobalQuotaAllowed();
     }
     
     /* Unlock the registry */
index f1dcc34..50c6815 100644 (file)
@@ -1,20 +1,19 @@
 /*
  * PROJECT:         ReactOS Kernel
- * LICENSE:         GPL - See COPYING in the top level directory
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
  * FILE:            ntoskrnl/config/cmboot.c
  * PURPOSE:         Configuration Manager - Boot Initialization
- * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ *                  Alex Ionescu (alex.ionescu@reactos.org)
  */
 
-/* INCLUDES ******************************************************************/
+/* INCLUDES *******************************************************************/
 
 #include "ntoskrnl.h"
 #define NDEBUG
 #include "debug.h"
-
-/* GLOBALS *******************************************************************/
-
-/* FUNCTIONS *****************************************************************/
+/* FUNCTIONS ******************************************************************/
 
 HCELL_INDEX
 NTAPI
@@ -124,3 +123,559 @@ CmpFindControlSet(IN PHHIVE SystemHive,
     /* Return the CCS Cell */
     return ControlSetCell;
 }
+
+ULONG
+NTAPI
+CmpFindTagIndex(IN PHHIVE Hive,
+                IN HCELL_INDEX TagCell,
+                IN HCELL_INDEX GroupOrderCell,
+                IN PUNICODE_STRING GroupName)
+{
+    PCM_KEY_VALUE TagValue, Value;
+    HCELL_INDEX OrderCell;
+    PULONG TagOrder, DriverTag;
+    ULONG CurrentTag, Length;
+    PCM_KEY_NODE Node;
+    BOOLEAN BufferAllocated;
+    ASSERT(Hive->ReleaseCellRoutine == NULL);
+    
+    /* Get the tag */
+    Value = HvGetCell(Hive, TagCell);
+    ASSERT(Value);
+    DriverTag = (PULONG)CmpValueToData(Hive, Value, &Length);
+    ASSERT(DriverTag);
+
+    /* Get the order array */
+    Node = HvGetCell(Hive, GroupOrderCell);
+    ASSERT(Node);
+    OrderCell = CmpFindValueByName(Hive, Node, GroupName);
+    if (OrderCell == HCELL_NIL) return -2;
+    
+    /* And read it */
+    TagValue = HvGetCell(Hive, OrderCell);
+    CmpGetValueData(Hive, TagValue, &Length, (PVOID*)&TagOrder, &BufferAllocated, &OrderCell);
+    ASSERT(TagOrder);
+    
+    /* Parse each tag */
+    for (CurrentTag = 1; CurrentTag <= TagOrder[0]; CurrentTag++)
+    {
+        /* Find a match */
+        if (TagOrder[CurrentTag] == *DriverTag)
+        {
+            /* Found it -- return the tag */
+            if (BufferAllocated) ExFreePool(TagOrder);
+            return CurrentTag;
+        }
+    }
+    
+    /* No matches, so assume next to last ordering */
+    if (BufferAllocated) ExFreePool(TagOrder);
+    return -2;
+}
+
+BOOLEAN
+NTAPI
+CmpAddDriverToList(IN PHHIVE Hive,
+                   IN HCELL_INDEX DriverCell,
+                   IN HCELL_INDEX GroupOrderCell,
+                   IN PUNICODE_STRING RegistryPath,
+                   IN PLIST_ENTRY BootDriverListHead)
+{
+    PBOOT_DRIVER_NODE DriverNode;
+    PBOOT_DRIVER_LIST_ENTRY DriverEntry;
+    PCM_KEY_NODE Node;
+    ULONG NameLength, Length;
+    HCELL_INDEX ValueCell, TagCell;    
+    PCM_KEY_VALUE Value;
+    PUNICODE_STRING FileName, RegistryString;
+    UNICODE_STRING UnicodeString;
+    PULONG ErrorControl;
+    PWCHAR Buffer;
+    ASSERT(Hive->ReleaseCellRoutine == NULL);
+    
+    /* Allocate a driver node and initialize it */
+    DriverNode = CmpAllocate(sizeof(BOOT_DRIVER_NODE), FALSE, TAG_CM);
+    if (!DriverNode) return FALSE;
+    DriverEntry = &DriverNode->ListEntry;
+    DriverEntry->RegistryPath.Buffer = NULL;
+    DriverEntry->FilePath.Buffer = NULL;
+    
+    /* Get the driver cell */
+    Node = HvGetCell(Hive, DriverCell);
+    ASSERT(Node);
+    
+    /* Get the name from the cell */
+    DriverNode->Name.Length = Node->Flags & KEY_COMP_NAME ? 
+                              CmpCompressedNameSize(Node->Name, Node->NameLength) :
+                              Node->NameLength;
+    DriverNode->Name.MaximumLength = DriverNode->Name.Length;
+    NameLength = DriverNode->Name.Length;
+    
+    /* Now allocate the buffer for it and copy the name */
+    DriverNode->Name.Buffer = CmpAllocate(NameLength, FALSE, TAG_CM);
+    if (!DriverNode->Name.Buffer) return FALSE;
+    if (Node->Flags & KEY_COMP_NAME)
+    {
+        /* Compressed name */
+        CmpCopyCompressedName(DriverNode->Name.Buffer,
+                              DriverNode->Name.Length,
+                              Node->Name,
+                              Node->NameLength);
+    }
+    else
+    {
+        /* Normal name */
+        RtlCopyMemory(DriverNode->Name.Buffer, Node->Name, Node->NameLength);
+    }
+    
+    /* Now find the image path */
+    RtlInitUnicodeString(&UnicodeString, L"ImagePath");
+    ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString);
+    if (ValueCell == HCELL_NIL)
+    {
+        /* Couldn't find it, so assume the drivers path */
+        Length = sizeof(L"System32\\Drivers\\") + NameLength + sizeof(L".sys");
+        
+        /* Allocate the path name */
+        FileName = &DriverEntry->FilePath;
+        FileName->Length = 0;
+        FileName->MaximumLength = Length;
+        FileName->Buffer = CmpAllocate(Length, FALSE,TAG_CM);
+        if (!FileName->Buffer) return FALSE;
+
+        /* Write the path name */
+        RtlAppendUnicodeToString(FileName, L"System32\\Drivers\\");
+        RtlAppendUnicodeStringToString(FileName, &DriverNode->Name);
+        RtlAppendUnicodeToString(FileName, L".sys");        
+    }
+    else
+    {
+        /* Path name exists, so grab it */
+        Value = HvGetCell(Hive, ValueCell);
+        ASSERT(Value);
+
+        /* Allocate and setup the path name */
+        FileName = &DriverEntry->FilePath;
+        Buffer = (PWCHAR)CmpValueToData(Hive, Value, &Length);
+        FileName->MaximumLength = FileName->Length = Length;
+        FileName->Buffer = CmpAllocate(Length, FALSE, TAG_CM);
+        
+        /* Transfer the data */  
+        if (!(FileName->Buffer) || !(Buffer)) return FALSE;        
+        RtlCopyMemory(FileName->Buffer, Buffer, Length);
+    }
+    
+    /* Now build the registry path */
+    RegistryString = &DriverEntry->RegistryPath;
+    RegistryString->Length = 0;
+    RegistryString->MaximumLength = RegistryPath->Length + NameLength;
+    RegistryString->Buffer = CmpAllocate(RegistryString->MaximumLength, FALSE, TAG_CM);
+    if (!RegistryString->Buffer) return FALSE;
+    
+    /* Add the driver name to it */
+    RtlAppendUnicodeStringToString(RegistryString, RegistryPath);
+    RtlAppendUnicodeStringToString(RegistryString, &DriverNode->Name);
+    
+    /* The entry is done, add it */
+    InsertHeadList(BootDriverListHead, &DriverEntry->Link);
+    
+    /* Now find error control settings */    
+    RtlInitUnicodeString(&UnicodeString, L"ErrorControl");
+    ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString);
+    if (ValueCell == HCELL_NIL)
+    {
+        /* Couldn't find it, so assume default */
+        DriverNode->ErrorControl = NormalError;
+    }
+    else
+    {
+        /* Otherwise, read whatever the data says */
+        Value = HvGetCell(Hive, ValueCell);
+        ASSERT(Value);
+        ErrorControl = (PULONG)CmpValueToData(Hive, Value, &Length);
+        ASSERT(ErrorControl);
+        DriverNode->ErrorControl = *ErrorControl;
+    }
+    
+    /* Next, get the group cell */
+    RtlInitUnicodeString(&UnicodeString, L"group");
+    ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString);
+    if (ValueCell == HCELL_NIL)
+    {
+        /* Couldn't find, so set an empty string */
+        RtlInitEmptyUnicodeString(&DriverNode->Group, NULL, 0);
+    }
+    else
+    {
+        /* Found it, read the group value */
+        Value = HvGetCell(Hive, ValueCell);
+        ASSERT(Value);
+        
+        /* Copy it into the node */
+        DriverNode->Group.Buffer = (PWCHAR)CmpValueToData(Hive, Value, &Length);
+        if (!DriverNode->Group.Buffer) return FALSE;
+        DriverNode->Group.Length = Length - sizeof(UNICODE_NULL);
+        DriverNode->Group.MaximumLength = DriverNode->Group.Length;
+    }
+    
+    /* Finally, find the tag */
+    RtlInitUnicodeString(&UnicodeString, L"Tag");
+    TagCell = CmpFindValueByName(Hive, Node, &UnicodeString);
+    if (TagCell == HCELL_NIL)
+    {
+        /* No tag, so load last */
+        DriverNode->Tag = -1;
+    }
+    else
+    {
+        /* Otherwise, decode it based on tag order */
+        DriverNode->Tag = CmpFindTagIndex(Hive,
+                                          TagCell,
+                                          GroupOrderCell,
+                                          &DriverNode->Group);
+    }
+    
+    /* All done! */
+    return TRUE;
+}
+
+BOOLEAN
+NTAPI
+CmpIsLoadType(IN PHHIVE Hive,
+              IN HCELL_INDEX Cell,
+              IN SERVICE_LOAD_TYPE LoadType)
+{
+    PCM_KEY_NODE Node;
+    HCELL_INDEX ValueCell;
+    UNICODE_STRING ValueString = RTL_CONSTANT_STRING(L"Start");
+    PCM_KEY_VALUE Value;
+    ULONG Length;
+    PLONG Data;
+    ASSERT(Hive->ReleaseCellRoutine == NULL);
+
+    /* Open the start cell */
+    Node = HvGetCell(Hive, Cell);
+    ASSERT(Node);
+    ValueCell = CmpFindValueByName(Hive, Node, &ValueString);
+    if (ValueCell == HCELL_NIL) return FALSE;
+    
+    /* Read the start value */
+    Value = HvGetCell(Hive, ValueCell);
+    ASSERT(Value);
+    Data = (PLONG)CmpValueToData(Hive, Value, &Length);
+    ASSERT(Data);
+    
+    /* Return if the type matches */
+    return (*Data == LoadType);
+}
+
+BOOLEAN
+NTAPI
+CmpFindDrivers(IN PHHIVE Hive,
+               IN HCELL_INDEX ControlSet,
+               IN SERVICE_LOAD_TYPE LoadType,
+               IN PWCHAR BootFileSystem OPTIONAL,
+               IN PLIST_ENTRY DriverListHead)
+{
+    HCELL_INDEX ServicesCell, ControlCell, GroupOrderCell, DriverCell;
+    UNICODE_STRING Name;
+    ULONG i;
+    WCHAR Buffer[128];
+    UNICODE_STRING UnicodeString, KeyPath;
+    PBOOT_DRIVER_NODE FsNode;
+    PCM_KEY_NODE ControlNode, ServicesNode, Node;
+    ASSERT(Hive->ReleaseCellRoutine == NULL);
+    
+    /* Open the control set key */
+    ControlNode = HvGetCell(Hive, ControlSet);
+    ASSERT(ControlNode);
+    
+    /* Get services cell */
+    RtlInitUnicodeString(&Name, L"Services");
+    ServicesCell = CmpFindSubKeyByName(Hive, ControlNode, &Name);
+    if (ServicesCell == HCELL_NIL) return FALSE;
+
+    /* Open services key */
+    ServicesNode = HvGetCell(Hive, ServicesCell);
+    ASSERT(ServicesNode);
+    
+    /* Get control cell */
+    RtlInitUnicodeString(&Name, L"Control");
+    ControlCell = CmpFindSubKeyByName(Hive, ControlNode, &Name);
+    if (ControlCell == HCELL_NIL) return FALSE;
+    
+    /* Get the group order cell and read it */
+    RtlInitUnicodeString(&Name, L"GroupOrderList");
+    Node = HvGetCell(Hive, ControlCell);
+    ASSERT(Node);
+    GroupOrderCell = CmpFindSubKeyByName(Hive, Node, &Name);
+    if (GroupOrderCell == HCELL_NIL) return FALSE;
+
+    /* Build the root registry path */
+    RtlInitEmptyUnicodeString(&KeyPath, Buffer, sizeof(Buffer));
+    RtlAppendUnicodeToString(&KeyPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
+    
+    /* Find the first subkey (ie: the first driver or service) */
+    i = 0;
+    DriverCell = CmpFindSubKeyByNumber(Hive, ServicesNode, i);
+    while (DriverCell != HCELL_NIL)
+    {
+        /* Make sure it's a driver of this start type */
+        if (CmpIsLoadType(Hive, DriverCell, LoadType))
+        {
+            /* Add it to the list */
+            CmpAddDriverToList(Hive,
+                               DriverCell,
+                               GroupOrderCell,
+                               &KeyPath,
+                               DriverListHead);
+            
+        }
+        
+        /* Try the next subkey */
+        DriverCell = CmpFindSubKeyByNumber(Hive, ServicesNode, ++i);
+    }
+    
+    /* Check if we have a boot file system */
+    if (BootFileSystem)
+    {
+        /* Find it */
+        RtlInitUnicodeString(&UnicodeString, BootFileSystem);
+        DriverCell = CmpFindSubKeyByName(Hive, ServicesNode, &UnicodeString);
+        if (DriverCell != HCELL_NIL)
+        {
+            /* Always add it to the list */
+            CmpAddDriverToList(Hive,
+                               DriverCell,
+                               GroupOrderCell,
+                               &KeyPath,
+                               DriverListHead);
+            
+            /* Mark it as critical so it always loads */
+            FsNode = CONTAINING_RECORD(DriverListHead->Flink,
+                                       BOOT_DRIVER_NODE,
+                                       ListEntry.Link);
+            FsNode->ErrorControl = SERVICE_ERROR_CRITICAL;
+        }
+    }
+    
+    /* We're done! */
+    return TRUE;
+}
+
+BOOLEAN
+NTAPI
+CmpDoSort(IN PLIST_ENTRY DriverListHead,
+          IN PUNICODE_STRING OrderList)
+{
+    PWCHAR Current, End = NULL;
+    PLIST_ENTRY NextEntry;
+    UNICODE_STRING GroupName;
+    PBOOT_DRIVER_NODE CurrentNode;
+    
+    /* We're going from end to start, so get to the last group and keep going */
+    Current = &OrderList->Buffer[OrderList->Length / sizeof(WCHAR)];
+    while (Current > OrderList->Buffer)
+    {
+        /* Scan the current string */
+        do
+        {
+            if (*Current == UNICODE_NULL) End = Current;
+        } while ((*(--Current - 1) != UNICODE_NULL) && (Current != OrderList->Buffer));
+
+        /* This is our cleaned up string for this specific group */
+        ASSERT(End != NULL);
+        GroupName.Length = (End - Current) * sizeof(WCHAR);
+        GroupName.MaximumLength = GroupName.Length;
+        GroupName.Buffer = Current;
+
+        /* Now loop the driver list */
+        NextEntry = DriverListHead->Flink;
+        while (NextEntry != DriverListHead)
+        {
+            /* Get this node */
+            CurrentNode = CONTAINING_RECORD(NextEntry,
+                                            BOOT_DRIVER_NODE,
+                                            ListEntry.Link);
+                                            
+            /* Get the next entry now since we'll do a relink */
+            NextEntry = CurrentNode->ListEntry.Link.Flink;
+            
+            /* Is there a group name and does it match the current group? */
+            if ((CurrentNode->Group.Buffer) &&
+                (RtlEqualUnicodeString(&GroupName, &CurrentNode->Group, TRUE)))
+            {
+                /* Remove from this location and re-link in the new one */
+                RemoveEntryList(&CurrentNode->ListEntry.Link);
+                InsertHeadList(DriverListHead, &CurrentNode->ListEntry.Link);
+            }
+        }        
+        
+        /* Move on */
+        Current--;
+    }
+    
+    /* All done */
+    return TRUE;
+}
+
+BOOLEAN
+NTAPI
+CmpSortDriverList(IN PHHIVE Hive,
+                  IN HCELL_INDEX ControlSet,
+                  IN PLIST_ENTRY DriverListHead)
+{
+    HCELL_INDEX Controls, GroupOrder, ListCell;
+    UNICODE_STRING Name, DependList;
+    PCM_KEY_VALUE ListNode;
+    ULONG Length;
+    PCM_KEY_NODE Node;
+    ASSERT(Hive->ReleaseCellRoutine == NULL);
+
+    /* Open the control key */
+    Node = HvGetCell(Hive, ControlSet);
+    ASSERT(Node);
+    RtlInitUnicodeString(&Name, L"Control");
+    Controls = CmpFindSubKeyByName(Hive, Node, &Name);
+    if (Controls == HCELL_NIL) return FALSE;
+
+    /* Open the service group order */
+    Node = HvGetCell(Hive, Controls);
+    ASSERT(Node);
+    RtlInitUnicodeString(&Name, L"ServiceGroupOrder");
+    GroupOrder = CmpFindSubKeyByName(Hive, Node, &Name);
+    if (GroupOrder == HCELL_NIL) return FALSE;
+
+    /* Open the list key */
+    Node = HvGetCell(Hive, GroupOrder);
+    ASSERT(Node);
+    RtlInitUnicodeString(&Name, L"list");
+    ListCell = CmpFindValueByName(Hive, Node, &Name);
+    if (ListCell == HCELL_NIL) return FALSE;
+    
+    /* Now read the actual list */
+    ListNode = HvGetCell(Hive, ListCell);
+    ASSERT(ListNode);
+    if (ListNode->Type != REG_MULTI_SZ) return FALSE;
+    
+    /* Copy it into a buffer */
+    DependList.Buffer = (PWCHAR)CmpValueToData(Hive, ListNode, &Length);
+    if (!DependList.Buffer) return FALSE;
+    DependList.Length = DependList.MaximumLength = Length - sizeof(UNICODE_NULL);
+    
+    /* And start the recurive sort algorithm */
+    return CmpDoSort(DriverListHead, &DependList);
+}
+
+BOOLEAN
+NTAPI
+CmpOrderGroup(IN PBOOT_DRIVER_NODE StartNode,
+              IN PBOOT_DRIVER_NODE EndNode)
+{
+    PBOOT_DRIVER_NODE CurrentNode, PreviousNode;
+    PLIST_ENTRY ListEntry;
+    
+    /* Base case, nothing to do */
+    if (StartNode == EndNode) return TRUE;
+    
+    /* Loop the nodes */
+    CurrentNode = StartNode;
+    do
+    {
+        /* Save this as the previous node */
+        PreviousNode = CurrentNode;
+        
+        /* And move to the next one */
+        ListEntry = CurrentNode->ListEntry.Link.Flink;
+        CurrentNode = CONTAINING_RECORD(ListEntry,
+                                        BOOT_DRIVER_NODE,
+                                        ListEntry.Link);
+        
+        /* Check if the previous driver had a bigger tag */
+        if (PreviousNode->Tag > CurrentNode->Tag)
+        {
+            /* Check if we need to update the tail */
+            if (CurrentNode == EndNode)
+            {
+                /* Update the tail */
+                ListEntry = CurrentNode->ListEntry.Link.Blink;
+                EndNode = CONTAINING_RECORD(ListEntry,
+                                            BOOT_DRIVER_NODE,
+                                            ListEntry.Link);
+            }
+            
+            /* Remove this driver since we need to move it */
+            RemoveEntryList(&CurrentNode->ListEntry.Link);
+            
+            /* Keep looping until we find a driver with a lower tag than ours */
+            while ((PreviousNode->Tag > CurrentNode->Tag) && (PreviousNode != StartNode))
+            {
+                /* We'll be re-inserted at this spot */
+                ListEntry = PreviousNode->ListEntry.Link.Blink;
+                PreviousNode = CONTAINING_RECORD(ListEntry,
+                                                 BOOT_DRIVER_NODE,
+                                                 ListEntry.Link);
+            }
+            
+            /* Do the insert in the new location */
+            InsertTailList(&PreviousNode->ListEntry.Link, &CurrentNode->ListEntry.Link);
+            
+            /* Update the head, if needed */
+            if (PreviousNode == StartNode) StartNode = CurrentNode;
+        }
+    } while (CurrentNode != EndNode);
+    
+    /* All done */
+    return TRUE;
+}
+
+BOOLEAN
+NTAPI
+CmpResolveDriverDependencies(IN PLIST_ENTRY DriverListHead)
+{
+    PLIST_ENTRY NextEntry;
+    PBOOT_DRIVER_NODE StartNode, EndNode, CurrentNode;
+    
+    /* Loop the list */
+    NextEntry = DriverListHead->Flink;
+    while (NextEntry != DriverListHead)
+    {
+        /* Find the first entry */
+        StartNode = CONTAINING_RECORD(NextEntry,
+                                      BOOT_DRIVER_NODE,
+                                      ListEntry.Link);
+        do
+        {
+            /* Find the last entry */
+            EndNode = CONTAINING_RECORD(NextEntry,
+                                        BOOT_DRIVER_NODE,
+                                        ListEntry.Link);
+            
+            /* Get the next entry */
+            NextEntry = NextEntry->Flink;
+            CurrentNode = CONTAINING_RECORD(NextEntry,
+                                            BOOT_DRIVER_NODE,
+                                            ListEntry.Link);
+            
+            /* If the next entry is back to the top, break out */
+            if (NextEntry == DriverListHead) break;
+            
+            /* Otherwise, check if this entry is equal */
+            if (!RtlEqualUnicodeString(&StartNode->Group,
+                                       &CurrentNode->Group,
+                                       TRUE))
+            {
+                /* It is, so we've detected a cycle, break out */
+                break;
+            }
+        } while (NextEntry != DriverListHead);
+        
+        /* Now we have the correct start and end pointers, so do the sort */
+        CmpOrderGroup(StartNode, EndNode);
+    }
+    
+    /* We're done */
+    return TRUE;
+}
+
+/* EOF */
index b3df10c..6dbf2a0 100644 (file)
@@ -11,7 +11,8 @@
 #include "ntoskrnl.h"
 #define NDEBUG
 #include "debug.h"
+#include "./../mm/ARM3/miarm.h"
+
 /* GLOBALS *******************************************************************/
 
 ULONG DummyData;
@@ -252,7 +253,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"DynamicMemory",
-        &DummyData,
+        &MmDynamicPfn,
         NULL,
         NULL
     },
@@ -260,7 +261,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"Mirroring",
-        &DummyData,
+        &MmMirroring,
         NULL,
         NULL
     },
@@ -273,14 +274,6 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
         NULL
     },
 
-    {
-        L"Session Manager\\Memory Management",
-        L"SessionViewSize",
-        &DummyData,
-        NULL,
-        NULL
-    },
-
     {
         L"Session Manager\\Memory Management",
         L"SessionImageSize",
@@ -300,7 +293,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"PoolUsageMaximum",
-        &DummyData,
+        &MmConsumedPoolPercentage,
         NULL,
         NULL
     },
@@ -308,7 +301,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"MapAllocationFragment",
-        &DummyData,
+        &MmAllocationFragment,
         NULL,
         NULL
     },
@@ -316,7 +309,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"PagedPoolSize",
-        &DummyData,
+        &MmSizeOfPagedPoolInBytes,
         NULL,
         NULL
     },
@@ -324,7 +317,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"NonPagedPoolSize",
-        &DummyData,
+        &MmSizeOfNonPagedPoolInBytes,
         NULL,
         NULL
     },
@@ -340,7 +333,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"LargeSystemCache",
-        &DummyData,
+        &MmLargeSystemCache,
         NULL,
         NULL
     },
@@ -356,7 +349,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"SystemPages",
-        &DummyData,
+        &MmNumberOfSystemPtes,
         NULL,
         NULL
     },
@@ -364,7 +357,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"LowMemoryThreshold",
-        &DummyData,
+        &MmLowMemoryThreshold,
         NULL,
         NULL
     },
@@ -372,7 +365,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"HighMemoryThreshold",
-        &DummyData,
+        &MmHighMemoryThreshold,
         NULL,
         NULL
     },
@@ -396,7 +389,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"SecondLevelDataCache",
-        &DummyData,
+        &MmSecondaryColors,
         NULL,
         NULL
     },
@@ -404,7 +397,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"ClearPageFileAtShutdown",
-        &DummyData,
+        &MmZeroPageFile,
         NULL,
         NULL
     },
@@ -452,7 +445,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"ProtectNonPagedPool",
-        &DummyData,
+        &MmProtectFreedNonPagedPool,
         NULL,
         NULL
     },
@@ -460,7 +453,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"TrackLockedPages",
-        &DummyData,
+        &MmTrackLockedPages,
         NULL,
         NULL
     },
@@ -468,7 +461,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"TrackPtes",
-        &DummyData,
+        &MmTrackPtes,
         NULL,
         NULL
     },
@@ -476,15 +469,15 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"VerifyDrivers",
-        &DummyData,
-        &DummyData,
-        &DummyData
+        MmVerifyDriverBuffer,
+        &MmVerifyDriverBufferLength,
+        &MmVerifyDriverBufferType
     },
 
     {
         L"Session Manager\\Memory Management",
         L"VerifyDriverLevel",
-        &DummyData,
+        &MmVerifyDriverLevel,
         NULL,
         NULL
     },
@@ -508,7 +501,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"EnforceWriteProtection",
-        &DummyData,
+        &MmEnforceWriteProtection,
         NULL,
         NULL
     },
@@ -516,7 +509,7 @@ CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
     {
         L"Session Manager\\Memory Management",
         L"MakeLowMemory",
-        &DummyData,
+        &MmMakeLowMemory,
         NULL,
         NULL
     },
index f4e9781..8fb2636 100644 (file)
 
 /* FUNCTIONS *****************************************************************/
 
+NTSTATUS
+NTAPI
+CmpAddToHiveFileList(IN PCMHIVE Hive)
+{
+    return STATUS_SUCCESS;
+}
+
 /* EOF */
\ No newline at end of file
index 154ba15..be7efc1 100644 (file)
@@ -119,12 +119,10 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     if (!Hive->ViewLock) return STATUS_INSUFFICIENT_RESOURCES;
 
     /* Allocate the flush lock */
-#if 0
     Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool,
                                               sizeof(ERESOURCE),
                                               TAG_CM);
     if (!Hive->FlusherLock) return STATUS_INSUFFICIENT_RESOURCES;
-#endif
 
     /* Setup the handles */
     Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary;
@@ -136,7 +134,7 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     Hive->ViewLockOwner = NULL;
 
     /* Initialize the flush lock */
-    ExInitializePushLock((PULONG_PTR)&Hive->FlusherLock);
+    ExInitializeResourceLite(Hive->FlusherLock);
 
     /* Setup hive locks */
     ExInitializePushLock((PULONG_PTR)&Hive->HiveLock);
@@ -193,9 +191,7 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     {
         /* Clear allocations and fail */
         ExFreePool(Hive->ViewLock);
-#if 0
         ExFreePool(Hive->FlusherLock);
-#endif
         ExFreePool(Hive);
         return Status;
     }
@@ -211,9 +207,7 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
         {
             /* Free all alocations */
             ExFreePool(Hive->ViewLock);
-#if 0
             ExFreePool(Hive->FlusherLock);
-#endif
             ExFreePool(Hive);
             return STATUS_REGISTRY_CORRUPT;
         }
index 5e7060d..a26de07 100644 (file)
@@ -1135,3 +1135,62 @@ DelistKeyBodyFromKCB(IN PCM_KEY_BODY KeyBody,
     /* Unlock it it if we did a manual lock */
     if (!LockHeld) CmpReleaseKcbLock(KeyBody->KeyControlBlock);
 }
+
+VOID
+NTAPI
+CmpFlushNotifiesOnKeyBodyList(IN PCM_KEY_CONTROL_BLOCK Kcb,
+                              IN BOOLEAN LockHeld)
+{
+    PLIST_ENTRY NextEntry, ListHead;
+    PCM_KEY_BODY KeyBody;
+
+    /* Sanity check */
+    LockHeld ? CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK() : CmpIsKcbLockedExclusive(Kcb);
+    while (TRUE)
+    {
+        /* Is the list empty? */
+        ListHead = &Kcb->KeyBodyListHead;
+        if (!IsListEmpty(ListHead))
+        {
+            /* Loop the list */
+            NextEntry = ListHead->Flink;
+            while (NextEntry != ListHead)
+            {
+                /* Get the key body */
+                KeyBody = CONTAINING_RECORD(NextEntry, CM_KEY_BODY, KeyBodyList);
+                ASSERT(KeyBody->Type == '20yk');
+
+                /* Check for notifications */
+                if (KeyBody->NotifyBlock)
+                {
+                    /* Is the lock held? */
+                    if (LockHeld)
+                    {
+                        /* Flush it */
+                        CmpFlushNotify(KeyBody, LockHeld);
+                        ASSERT(KeyBody->NotifyBlock == NULL);
+                        continue;
+                    }
+                    
+                    /* Lock isn't held, so we need to take a reference */
+                    if (ObReferenceObjectSafe(KeyBody))
+                    {
+                        /* Now we can flush */
+                        CmpFlushNotify(KeyBody, LockHeld);
+                        ASSERT(KeyBody->NotifyBlock == NULL);
+                        
+                        /* Release the reference we took */
+                                   ObDereferenceObjectDeferDelete(KeyBody);
+                        continue;
+                    }
+                }
+
+                /* Try the next entry */
+                NextEntry = NextEntry->Flink;
+            }
+        }
+        
+        /* List has been parsed, exit */
+        break;
+    }
+}
index 42d7379..8263544 100644 (file)
@@ -414,15 +414,6 @@ CmpDoCreate(IN PHHIVE Hive,
     LARGE_INTEGER TimeStamp;
     PCM_KEY_NODE KeyNode;
 
-    /* Sanity check */
-#if 0
-    ASSERT((CmpIsKcbLockedExclusive(ParentKcb) == TRUE) ||
-           (CmpTestRegistryLockExclusive() == TRUE));
-#endif
-
-    /* Acquire the flusher lock */
-    ExAcquirePushLockShared((PVOID)&((PCMHIVE)Hive)->FlusherLock);
-
     /* Check if the parent is being deleted */
     if (ParentKcb->Delete)
     {
@@ -555,7 +546,6 @@ CmpDoCreate(IN PHHIVE Hive,
 
 Exit:
     /* Release the flusher lock and return status */
-    ExReleasePushLock((PVOID)&((PCMHIVE)Hive)->FlusherLock);
     return Status;
 }
 
@@ -747,9 +737,6 @@ CmpCreateLinkNode(IN PHHIVE Hive,
     LARGE_INTEGER TimeStamp;
     PCM_KEY_NODE KeyNode;
     PCM_KEY_CONTROL_BLOCK Kcb = ParentKcb;
-#if 0
-    CMP_ASSERT_REGISTRY_LOCK();
-#endif
 
     /* Link nodes only allowed on the master */
     if (Hive != &CmiVolatileHive->Hive)
@@ -759,10 +746,6 @@ CmpCreateLinkNode(IN PHHIVE Hive,
         return STATUS_ACCESS_DENIED;
     }
     
-    /* Acquire the flusher locks */
-    ExAcquirePushLockShared((PVOID)&((PCMHIVE)Hive)->FlusherLock);
-    ExAcquirePushLockShared((PVOID)&((PCMHIVE)Context->ChildHive.KeyHive)->FlusherLock);
-
     /* Check if the parent is being deleted */
     if (ParentKcb->Delete)
     {
@@ -964,8 +947,6 @@ CmpCreateLinkNode(IN PHHIVE Hive,
     
 Exit:
     /* Release the flusher locks and return status */
-    ExReleasePushLock((PVOID)&((PCMHIVE)Context->ChildHive.KeyHive)->FlusherLock);
-    ExReleasePushLock((PVOID)&((PCMHIVE)Hive)->FlusherLock);
     return Status;
 }
 
index 0326e88..3587efe 100644 (file)
@@ -1,12 +1,13 @@
 /*
  * PROJECT:         ReactOS Kernel
- * LICENSE:         GPL - See COPYING in the top level directory
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
  * FILE:            ntoskrnl/config/cmsysini.c
  * PURPOSE:         Configuration Manager - System Initialization Code
- * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ *                  Alex Ionescu (alex.ionescu@reactos.org)
  */
 
-/* INCLUDES ******************************************************************/
+/* INCLUDES *******************************************************************/
 
 #include "ntoskrnl.h"
 #define NDEBUG
@@ -33,7 +34,7 @@ ULONG CmpTraceLevel = 0;
 extern LONG CmpFlushStarveWriters;
 extern BOOLEAN CmFirstTime;
 
-/* FUNCTIONS *****************************************************************/
+/* FUNCTIONS ******************************************************************/
 
 VOID
 NTAPI
@@ -1574,6 +1575,162 @@ CmInitSystem1(VOID)
     return TRUE;
 }
 
+VOID
+NTAPI
+CmpFreeDriverList(IN PHHIVE Hive,
+                  IN PLIST_ENTRY DriverList)
+{
+    PLIST_ENTRY NextEntry, OldEntry;
+    PBOOT_DRIVER_NODE DriverNode;
+    PAGED_CODE();
+    
+    /* Parse the current list */
+    NextEntry = DriverList->Flink;
+    while (NextEntry != DriverList)
+    {
+        /* Get the driver node */
+        DriverNode = CONTAINING_RECORD(NextEntry, BOOT_DRIVER_NODE, ListEntry.Link);
+        
+        /* Get the next entry now, since we're going to free it later */
+        OldEntry = NextEntry;
+        NextEntry = NextEntry->Flink;
+        
+        /* Was there a name? */
+        if (DriverNode->Name.Buffer)
+        {
+            /* Free it */
+            CmpFree(DriverNode->Name.Buffer, DriverNode->Name.Length);
+        }
+        
+        /* Was there a registry path? */
+        if (DriverNode->ListEntry.RegistryPath.Buffer)
+        {
+            /* Free it */
+            CmpFree(DriverNode->ListEntry.RegistryPath.Buffer, 
+                    DriverNode->ListEntry.RegistryPath.MaximumLength);
+        }
+        
+        /* Was there a file path? */
+        if (DriverNode->ListEntry.FilePath.Buffer)
+        {
+            /* Free it */
+            CmpFree(DriverNode->ListEntry.FilePath.Buffer,
+                    DriverNode->ListEntry.FilePath.MaximumLength);
+        }
+        
+        /* Now free the node, and move on */
+        CmpFree(OldEntry, sizeof(BOOT_DRIVER_NODE));
+    }
+}
+
+PUNICODE_STRING*
+NTAPI
+CmGetSystemDriverList(VOID)
+{
+    LIST_ENTRY DriverList;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    NTSTATUS Status;
+    PCM_KEY_BODY KeyBody;
+    PHHIVE Hive;
+    HCELL_INDEX RootCell, ControlCell;
+    HANDLE KeyHandle;
+    UNICODE_STRING KeyName;
+    PLIST_ENTRY NextEntry;
+    ULONG i;
+    PUNICODE_STRING* ServicePath = NULL;
+    BOOLEAN Success, AutoSelect;
+    PBOOT_DRIVER_LIST_ENTRY DriverEntry;
+    PAGED_CODE();
+
+    /* Initialize the driver list */
+    InitializeListHead(&DriverList);
+    
+    /* Open the system hive key */
+    RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = NtOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
+    if (!NT_SUCCESS(Status)) return NULL;
+    
+    /* Reference the key object to get the root hive/cell to access directly */
+    Status = ObReferenceObjectByHandle(KeyHandle,
+                                       KEY_QUERY_VALUE,
+                                       CmpKeyObjectType,
+                                       KernelMode,
+                                       (PVOID*)&KeyBody,
+                                       NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        NtClose(KeyHandle);
+        return NULL;
+    }
+    
+    /* Do all this under the registry lock */
+    CmpLockRegistryExclusive();
+    
+    /* Get the hive and key cell */
+    Hive = KeyBody->KeyControlBlock->KeyHive;
+    RootCell = KeyBody->KeyControlBlock->KeyCell;
+    
+    /* Open the current control set key */
+    RtlInitUnicodeString(&KeyName, L"Current");
+    ControlCell = CmpFindControlSet(Hive, RootCell, &KeyName, &AutoSelect);
+    if (ControlCell == HCELL_NIL) goto EndPath;
+    
+    /* Find all system drivers */
+    Success = CmpFindDrivers(Hive, ControlCell, SystemLoad, NULL, &DriverList);
+    if (!Success) goto EndPath;
+    
+    /* Sort by group/tag */
+    if (!CmpSortDriverList(Hive, ControlCell, &DriverList)) goto EndPath;
+    
+    /* Remove circular dependencies (cycles) and sort */
+    if (!CmpResolveDriverDependencies(&DriverList)) goto EndPath;
+    
+    /* Loop the list to count drivers */
+    for (i = 0, NextEntry = DriverList.Flink;
+         NextEntry != &DriverList;
+         i++, NextEntry = NextEntry->Flink);
+    
+    /* Allocate the array */
+    ServicePath = ExAllocatePool(NonPagedPool, (i + 1) * sizeof(PUNICODE_STRING));
+    if (!ServicePath) KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
+    
+    /* Loop the driver list */
+    for (i = 0, NextEntry = DriverList.Flink;
+         NextEntry != &DriverList;
+         i++, NextEntry = NextEntry->Flink)
+    {
+        /* Get the entry */
+        DriverEntry = CONTAINING_RECORD(NextEntry, BOOT_DRIVER_LIST_ENTRY, Link);
+
+        /* Allocate the path for the caller and duplicate the registry path */
+        ServicePath[i] = ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING));
+        RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
+                                  &DriverEntry->RegistryPath,
+                                  ServicePath[i]);
+    }
+    
+    /* Terminate the list */
+    ServicePath[i] = NULL;
+    
+EndPath:
+    /* Free the driver list if we had one */
+    if (!IsListEmpty(&DriverList)) CmpFreeDriverList(Hive, &DriverList);
+    
+    /* Unlock the registry */
+    CmpUnlockRegistry();
+    
+    /* Close the key handle and dereference the object, then return the path */
+    ObDereferenceObject(KeyBody);
+    NtClose(KeyHandle);
+    return ServicePath;
+}
+
 VOID
 NTAPI
 CmpLockRegistryExclusive(VOID)
@@ -1771,3 +1928,5 @@ CmShutdownSystem(VOID)
     if (!CmFirstTime) CmpShutdownWorkers();
     CmpDoFlushAll(TRUE);
 }
+
+/* EOF */
index 4880dc0..62f4010 100644 (file)
@@ -1522,6 +1522,40 @@ CmSetLazyFlushState(
     IN BOOLEAN Enable
 );
 
+//
+// Driver List Routines
+//
+PUNICODE_STRING*
+NTAPI
+CmGetSystemDriverList(
+    VOID
+);
+
+BOOLEAN
+NTAPI
+CmpFindDrivers(
+    IN PHHIVE Hive,
+    IN HCELL_INDEX ControlSet,
+    IN SERVICE_LOAD_TYPE LoadType,
+    IN PWSTR BootFileSystem OPTIONAL,
+    IN PLIST_ENTRY DriverListHead
+);
+
+
+BOOLEAN
+NTAPI
+CmpSortDriverList(
+    IN PHHIVE Hive,
+    IN HCELL_INDEX ControlSet,
+    IN PLIST_ENTRY DriverListHead
+);
+
+BOOLEAN
+NTAPI
+CmpResolveDriverDependencies(
+    IN PLIST_ENTRY DriverListHead
+);
+
 //
 // Global variables accessible from all of Cm
 //
index a78497b..6cb2a7c 100644 (file)
@@ -42,11 +42,11 @@ Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea)
     extern ULONG KeI386FxsrPresent;
     if (KeI386FxsrPresent)
     {
-        __asm__ __volatile__ ("fxsave %0\n" : : "m"(SaveArea));
+        __asm__ __volatile__ ("fxsave %0\n" : : "m"(*SaveArea));
     }
     else
     {
-        __asm__ __volatile__ ("fnsave %0\n wait\n" : : "m"(SaveArea));
+        __asm__ __volatile__ ("fnsave %0\n wait\n" : : "m"(*SaveArea));
     }
 }
 
@@ -136,17 +136,27 @@ Ke386FnInit(VOID)
 
 FORCEINLINE
 VOID
-Ke386GetGlobalDescriptorTable(OUT PVOID Descriptor)
+__sgdt(OUT PVOID Descriptor)
 {
-    __asm sgdt [Descriptor];
+    __asm
+    {
+        mov eax, Descriptor
+        sgdt [eax]
+    }
 }
+#define Ke386GetGlobalDescriptorTable __sgdt
 
 FORCEINLINE
 VOID
-Ke386SetGlobalDescriptorTable(IN PVOID Descriptor)
+__lgdt(IN PVOID Descriptor)
 {
-    __asm lgdt [Descriptor];
+    __asm
+    {
+        mov eax, Descriptor
+        lgdt [eax]
+    }
 }
+#define Ke386SetGlobalDescriptorTable __lgdt
 
 FORCEINLINE
 USHORT
index 2519a81..9398ef1 100644 (file)
 #define IopFreeMdlFromLookaside                         \
     ObpFreeCapturedAttributes
 
-//
-// Returns the size of a CM_RESOURCE_LIST
-//
-#define CM_RESOURCE_LIST_SIZE(ResList)                  \
-    (ResList->Count == 1) ?                             \
-        FIELD_OFFSET(                                   \
-            CM_RESOURCE_LIST,                           \
-            List[0].PartialResourceList.                \
-            PartialDescriptors[(ResList)->              \
-                               List[0].                 \
-                               PartialResourceList.     \
-                               Count])                  \
-        :                                               \
-        FIELD_OFFSET(CM_RESOURCE_LIST, List)
-
 //
 // Determines if the IRP is Synchronous
 //
@@ -395,6 +380,33 @@ typedef struct _LOAD_UNLOAD_PARAMS
     PDRIVER_OBJECT DriverObject;
 } LOAD_UNLOAD_PARAMS, *PLOAD_UNLOAD_PARAMS;
 
+//
+// Boot Driver List Entry
+//
+typedef struct _DRIVER_INFORMATION
+{
+    LIST_ENTRY Link;
+    PDRIVER_OBJECT DriverObject;
+    PBOOT_DRIVER_LIST_ENTRY DataTableEntry;
+    HANDLE ServiceHandle;
+    USHORT TagPosition;
+    ULONG Failed;
+    ULONG Processed;
+    NTSTATUS Status;
+} DRIVER_INFORMATION, *PDRIVER_INFORMATION;
+
+//
+// Boot Driver Node
+//
+typedef struct _BOOT_DRIVER_NODE
+{
+    BOOT_DRIVER_LIST_ENTRY ListEntry;
+    UNICODE_STRING Group;
+    UNICODE_STRING Name;
+    ULONG Tag;
+    ULONG ErrorControl;
+} BOOT_DRIVER_NODE, *PBOOT_DRIVER_NODE;
 //
 // List of Bus Type GUIDs
 //
@@ -479,11 +491,35 @@ typedef struct _DEVICETREE_TRAVERSE_CONTEXT
     PVOID Context;
 } DEVICETREE_TRAVERSE_CONTEXT, *PDEVICETREE_TRAVERSE_CONTEXT;
 
+//
+// Resource code
+//
+ULONG
+NTAPI
+IopCalculateResourceListSize(
+    IN PCM_RESOURCE_LIST ResourceList
+);
+
+NTSTATUS
+NTAPI
+IopAssignDeviceResources(
+    IN PDEVICE_NODE DeviceNode
+);
+
 //
 // PNP Routines
 //
-VOID
-PnpInit(
+NTSTATUS
+NTAPI
+PipCallDriverAddDevice(
+    IN PDEVICE_NODE DeviceNode,
+    IN BOOLEAN LoadDriver,     
+    IN PDRIVER_OBJECT DriverObject
+);
+
+NTSTATUS
+NTAPI
+IopInitializePlugPlayServices(
     VOID
 );
 
@@ -522,6 +558,12 @@ IopGetSystemPowerDeviceObject(
     IN PDEVICE_OBJECT *DeviceObject
 );
 
+PDEVICE_NODE
+NTAPI
+PipAllocateDeviceNode(
+    IN PDEVICE_OBJECT PhysicalDeviceObject
+);
+
 NTSTATUS
 IopCreateDeviceNode(
     IN PDEVICE_NODE ParentNode,
@@ -536,6 +578,15 @@ IopFreeDeviceNode(
 );
 
 NTSTATUS
+NTAPI
+IopSynchronousCall(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIO_STACK_LOCATION IoStackLocation,
+    OUT PVOID *Information
+);
+
+NTSTATUS
+NTAPI
 IopInitiatePnpIrp(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIO_STATUS_BLOCK IoStatusBlock,
@@ -600,11 +651,66 @@ IopOpenRegistryKeyEx(
 
 NTSTATUS
 NTAPI
-IopGetRegistryValue(IN HANDLE Handle,
-                    IN PWSTR ValueName,
-                    OUT PKEY_VALUE_FULL_INFORMATION *Information);
+IopGetRegistryValue(
+    IN HANDLE Handle,
+    IN PWSTR ValueName,
+    OUT PKEY_VALUE_FULL_INFORMATION *Information
+);
 
+NTSTATUS
+NTAPI
+IopCreateRegistryKeyEx(
+    OUT PHANDLE Handle,
+    IN HANDLE BaseHandle OPTIONAL,
+    IN PUNICODE_STRING KeyName,
+    IN ACCESS_MASK DesiredAccess,
+    IN ULONG CreateOptions,
+    OUT PULONG Disposition OPTIONAL
+);
 
+//
+// PnP Routines
+//
+NTSTATUS
+NTAPI
+IopUpdateRootKey(
+    VOID
+);
+
+NTSTATUS
+NTAPI
+PiInitCacheGroupInformation(
+    VOID
+);
+
+USHORT
+NTAPI
+PpInitGetGroupOrderIndex(
+    IN HANDLE ServiceHandle
+);
+
+USHORT
+NTAPI
+PipGetDriverTagPriority(
+    IN HANDLE ServiceHandle
+);
+
+NTSTATUS
+NTAPI
+PnpRegMultiSzToUnicodeStrings(
+    IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation,
+    OUT PUNICODE_STRING *UnicodeStringList,
+    OUT PULONG UnicodeStringCount
+);
+
+BOOLEAN
+NTAPI
+PnpRegSzToString(
+    IN PWCHAR RegSzData,
+    IN ULONG RegSzLength,
+    OUT PUSHORT StringLength OPTIONAL
+);
+                                               
 //
 // Initialization Routines
 //
@@ -630,6 +736,12 @@ IoInitSystem(
 //
 // Device/Volume Routines
 //
+VOID
+NTAPI
+IopReadyDeviceObjects(
+    IN PDRIVER_OBJECT Driver
+);
+
 NTSTATUS
 FASTCALL
 IopInitializeDevice(
@@ -1051,6 +1163,7 @@ IopStartRamdisk(
 //
 extern POBJECT_TYPE IoCompletionType;
 extern PDEVICE_NODE IopRootDeviceNode;
+extern KSPIN_LOCK IopDeviceTreeLock;
 extern ULONG IopTraceLevel;
 extern GENERAL_LOOKASIDE IopMdlLookasideList;
 extern GENERIC_MAPPING IopCompletionMapping;
@@ -1060,6 +1173,8 @@ extern HAL_DISPATCH _HalDispatchTable;
 extern LIST_ENTRY IopErrorLogListHead;
 extern ULONG IopNumTriageDumpDataBlocks;
 extern PVOID IopTriageDumpDataBlocks[64];
+extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList;
+extern PDRIVER_OBJECT IopRootDriverObject;
 
 //
 // Inlined Functions
index 7434970..b9176ce 100644 (file)
@@ -25,6 +25,24 @@ extern LIST_ENTRY IopTapeFsListHead;
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
+VOID
+NTAPI
+IopReadyDeviceObjects(IN PDRIVER_OBJECT Driver)
+{
+    PAGED_CODE();
+    PDEVICE_OBJECT DeviceObject;
+
+    /* Set the driver as initialized */
+    Driver->Flags |= DRVO_INITIALIZED;
+    DeviceObject = Driver->DeviceObject;
+    while (DeviceObject)
+    {
+        /* Set every device as initialized too */
+        DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+        DeviceObject = DeviceObject->NextDevice;
+    }
+}
+
 VOID
 NTAPI
 IopDeleteDevice(IN PVOID ObjectBody)
index 2b0789b..a9b5e47 100644 (file)
 
 static PWCHAR BaseKeyString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\";
 
+static
+NTSTATUS
+OpenRegistryHandlesFromSymbolicLink(IN PUNICODE_STRING SymbolicLinkName,
+                                    IN ACCESS_MASK DesiredAccess,
+                                    IN OPTIONAL PHANDLE GuidKey,
+                                    IN OPTIONAL PHANDLE DeviceKey,
+                                    IN OPTIONAL PHANDLE InstanceKey)
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    WCHAR PathBuffer[MAX_PATH];
+    UNICODE_STRING BaseKeyU;
+    UNICODE_STRING GuidString, SubKeyName, ReferenceString;
+    PWCHAR StartPosition, EndPosition;
+    HANDLE ClassesKey;
+    PHANDLE GuidKeyRealP, DeviceKeyRealP, InstanceKeyRealP;
+    HANDLE GuidKeyReal, DeviceKeyReal, InstanceKeyReal;
+    NTSTATUS Status;
+
+    SubKeyName.Buffer = NULL;
+
+    if (GuidKey != NULL)
+        GuidKeyRealP = GuidKey;
+    else
+        GuidKeyRealP = &GuidKeyReal;
+
+    if (DeviceKey != NULL)
+        DeviceKeyRealP = DeviceKey;
+    else
+        DeviceKeyRealP = &DeviceKeyReal;
+
+    if (InstanceKey != NULL)
+        InstanceKeyRealP = InstanceKey;
+    else
+        InstanceKeyRealP = &InstanceKeyReal;
+
+    *GuidKeyRealP = INVALID_HANDLE_VALUE;
+    *DeviceKeyRealP = INVALID_HANDLE_VALUE;
+    *InstanceKeyRealP = INVALID_HANDLE_VALUE;
+
+    BaseKeyU.Buffer = PathBuffer;
+    BaseKeyU.Length = 0;
+    BaseKeyU.MaximumLength = MAX_PATH * sizeof(WCHAR);
+
+    RtlAppendUnicodeToString(&BaseKeyU, BaseKeyString);
+
+    /* Open the DeviceClasses key */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &BaseKeyU,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
+    Status = ZwOpenKey(&ClassesKey,
+                       DesiredAccess | KEY_ENUMERATE_SUB_KEYS,
+                       &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open %wZ\n", &BaseKeyU);
+        goto cleanup;
+    }
+
+    StartPosition = wcschr(SymbolicLinkName->Buffer, L'{');
+    EndPosition = wcschr(SymbolicLinkName->Buffer, L'}');
+    if (!StartPosition || !EndPosition || StartPosition > EndPosition)
+    {
+        DPRINT1("Bad symbolic link: %wZ\n", SymbolicLinkName);
+        return STATUS_INVALID_PARAMETER_1;
+    }
+    GuidString.Buffer = StartPosition;
+    GuidString.MaximumLength = GuidString.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)StartPosition);
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &GuidString,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               ClassesKey,
+                               NULL);
+    Status = ZwOpenKey(GuidKeyRealP,
+                       DesiredAccess | KEY_ENUMERATE_SUB_KEYS,
+                       &ObjectAttributes);
+    ZwClose(ClassesKey);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open %wZ%wZ (%x)\n", &BaseKeyU, &GuidString, Status);
+        goto cleanup;
+    }
+
+    SubKeyName.Buffer = ExAllocatePool(PagedPool, SymbolicLinkName->Length);
+    if (!SubKeyName.Buffer)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto cleanup;
+    }
+    SubKeyName.MaximumLength = SymbolicLinkName->Length;
+    SubKeyName.Length = 0;
+
+    RtlAppendUnicodeStringToString(&SubKeyName,
+                                   SymbolicLinkName);
+
+    SubKeyName.Buffer[0] = L'#';
+    SubKeyName.Buffer[1] = L'#';
+    SubKeyName.Buffer[2] = L'?';
+    SubKeyName.Buffer[3] = L'#';
+
+    ReferenceString.Buffer = wcsrchr(SubKeyName.Buffer, '\\');
+    if (ReferenceString.Buffer != NULL)
+    {
+        ReferenceString.Buffer[0] = L'#';
+
+        SubKeyName.Length = (USHORT)((ULONG_PTR)(ReferenceString.Buffer) - (ULONG_PTR)SubKeyName.Buffer);
+        ReferenceString.Length = SymbolicLinkName->Length - SubKeyName.Length;
+    }
+    else
+    {
+        RtlInitUnicodeString(&ReferenceString, L"#");
+    }
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &SubKeyName,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               *GuidKeyRealP,
+                               NULL);
+    Status = ZwOpenKey(DeviceKeyRealP,
+                       DesiredAccess | KEY_ENUMERATE_SUB_KEYS,
+                       &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open %wZ%wZ\\%wZ\n", &BaseKeyU, &GuidString, &SubKeyName);
+        goto cleanup;
+    }
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &ReferenceString,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               *DeviceKeyRealP,
+                               NULL);
+    Status = ZwOpenKey(InstanceKeyRealP,
+                       DesiredAccess,
+                       &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open %wZ%wZ\\%wZ%\\%wZ (%x)\n", &BaseKeyU, &GuidString, &SubKeyName, &ReferenceString, Status);
+        goto cleanup;
+    }
+
+    Status = STATUS_SUCCESS;
+
+cleanup:
+    if (SubKeyName.Buffer != NULL)
+       ExFreePool(SubKeyName.Buffer);
+
+    if (NT_SUCCESS(Status))
+    {
+       if (!GuidKey)
+          ZwClose(*GuidKeyRealP);
+
+       if (!DeviceKey)
+          ZwClose(*DeviceKeyRealP);
+
+       if (!InstanceKey)
+          ZwClose(*InstanceKeyRealP);
+    }
+    else
+    {
+       if (*GuidKeyRealP != INVALID_HANDLE_VALUE)
+          ZwClose(*GuidKeyRealP);
+
+       if (*DeviceKeyRealP != INVALID_HANDLE_VALUE)
+          ZwClose(*DeviceKeyRealP);
+
+       if (*InstanceKeyRealP != INVALID_HANDLE_VALUE)
+          ZwClose(*InstanceKeyRealP);
+    }
+
+    return Status;
+}
 /*++
  * @name IoOpenDeviceInterfaceRegistryKey
  * @unimplemented
@@ -50,169 +224,37 @@ IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName,
                                  IN ACCESS_MASK DesiredAccess,
                                  OUT PHANDLE DeviceInterfaceKey)
 {
-    WCHAR StrBuff[MAX_PATH], PathBuff[MAX_PATH];
-    PWCHAR Guid;
-    UNICODE_STRING EnumU = RTL_CONSTANT_STRING(ENUM_ROOT L"\\");
-    UNICODE_STRING DevParamU = RTL_CONSTANT_STRING(L"\\Device Parameters");
-    UNICODE_STRING PrefixU = RTL_CONSTANT_STRING(L"\\??\\");
-    UNICODE_STRING KeyPath, KeyName;
-    UNICODE_STRING MatchableGuid;
-    HANDLE GuidKey, ChildKey;
-    ULONG Index = 0;
-    PKEY_BASIC_INFORMATION KeyInformation;
-    ULONG KeyInformationLength;
-    PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
-    ULONG KeyValueInformationLength;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    NTSTATUS Status;
-    ULONG RequiredLength;
-
-    MatchableGuid.Length = 0;
-    MatchableGuid.Length += swprintf(StrBuff,
-                                     L"##?#%ls",
-                                     &SymbolicLinkName->Buffer[PrefixU.Length / sizeof(WCHAR)]);
-    StrBuff[++MatchableGuid.Length] = UNICODE_NULL;
-
-    MatchableGuid.Buffer = StrBuff;
-    MatchableGuid.MaximumLength = MAX_PATH * sizeof(WCHAR);
-    MatchableGuid.Length = (MatchableGuid.Length-1) * sizeof(WCHAR);
-
-    Guid = wcsstr(StrBuff, L"{");
-    if (!Guid)
-        return STATUS_OBJECT_NAME_NOT_FOUND;
-
-    KeyPath.Buffer = PathBuff;
-    KeyPath.Length = 0;
-    KeyPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
-
-    RtlAppendUnicodeToString(&KeyPath, BaseKeyString);
-    RtlAppendUnicodeToString(&KeyPath, Guid);
-
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &KeyPath,
-                               OBJ_CASE_INSENSITIVE,
-                               0,
-                               NULL);
-
-    Status = ZwOpenKey(&GuidKey, KEY_CREATE_SUB_KEY, &ObjectAttributes);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
-    while (TRUE)
-    {
-        Status = ZwEnumerateKey(GuidKey,
-                                Index,
-                                KeyBasicInformation,
-                                NULL,
-                                0,
-                                &RequiredLength);
-        if (Status == STATUS_NO_MORE_ENTRIES)
-            break;
-        else if (Status == STATUS_BUFFER_TOO_SMALL)
-        {
-            KeyInformationLength = RequiredLength;
-            KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength);
-            if (!KeyInformation)
-            {
-                ZwClose(GuidKey);
-                return STATUS_INSUFFICIENT_RESOURCES;
-            }
-
-            Status = ZwEnumerateKey(GuidKey,
-                                    Index,
-                                    KeyBasicInformation,
-                                    KeyInformation,
-                                    KeyInformationLength,
-                                    &RequiredLength);
-        }
-        else
-        {
-            ZwClose(GuidKey);
-            return STATUS_OBJECT_PATH_NOT_FOUND;
-        }
-        Index++;
-
-        if (!NT_SUCCESS(Status))
-        {
-            ZwClose(GuidKey);
-            return Status;
-        }
-
-        KeyName.Length = KeyName.MaximumLength = KeyInformation->NameLength;
-        KeyName.Buffer = KeyInformation->Name;
-
-        if (!RtlEqualUnicodeString(&KeyName, &MatchableGuid, TRUE))
-            continue;
-
-        InitializeObjectAttributes(&ObjectAttributes,
-                                   &KeyName,
-                                   OBJ_CASE_INSENSITIVE,
-                                   GuidKey,
-                                   NULL);
-        Status = ZwOpenKey(&ChildKey, KEY_QUERY_VALUE, &ObjectAttributes);
-        ZwClose(GuidKey);
-        if (!NT_SUCCESS(Status))
-            return Status;
-
-        RtlInitUnicodeString(&KeyName, L"DeviceInstance");
-        Status = ZwQueryValueKey(ChildKey,
-                                 &KeyName,
-                                 KeyValuePartialInformation,
-                                 NULL,
-                                 0,
-                                 &RequiredLength);
-        if (Status == STATUS_BUFFER_TOO_SMALL)
-        {
-            KeyValueInformationLength = RequiredLength;
-            KeyValueInformation = ExAllocatePool(PagedPool, KeyValueInformationLength);
-            if (!KeyValueInformation)
-            {
-                ZwClose(ChildKey);
-                return Status;
-            }
-
-            Status = ZwQueryValueKey(ChildKey,
-                                     &KeyName,
-                                     KeyValuePartialInformation,
-                                     KeyValueInformation,
-                                     KeyValueInformationLength,
-                                     &RequiredLength);
-        }
-        else
-        {
-            ZwClose(ChildKey);
-            return STATUS_OBJECT_PATH_NOT_FOUND;
-        }
-        ZwClose(ChildKey);
-
-        if (!NT_SUCCESS(Status))
-            return Status;
-
-        KeyPath.Length = 0;
-
-        KeyName.Length = KeyName.MaximumLength = KeyValueInformation->DataLength;
-        KeyName.Buffer = (PWCHAR)KeyValueInformation->Data;
-
-        RtlAppendUnicodeStringToString(&KeyPath, &EnumU);
-        RtlAppendUnicodeStringToString(&KeyPath, &KeyName);
-        RtlAppendUnicodeStringToString(&KeyPath, &DevParamU);
-
-        InitializeObjectAttributes(&ObjectAttributes,
-                                   &KeyPath,
-                                   OBJ_CASE_INSENSITIVE,
-                                   0,
-                                   NULL);
-        Status = ZwCreateKey(DeviceInterfaceKey,
-                             DesiredAccess,
-                             &ObjectAttributes,
-                             0,
-                             NULL,
-                             REG_OPTION_NON_VOLATILE,
-                             NULL);
-        return Status;
-    }
-
-    return STATUS_OBJECT_PATH_NOT_FOUND;
+   HANDLE InstanceKey, DeviceParametersKey;
+   NTSTATUS Status;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   UNICODE_STRING DeviceParametersU = RTL_CONSTANT_STRING(L"Device Parameters");
+
+   Status = OpenRegistryHandlesFromSymbolicLink(SymbolicLinkName,
+                                                KEY_CREATE_SUB_KEY,
+                                                NULL,
+                                                NULL,
+                                                &InstanceKey);
+   if (!NT_SUCCESS(Status))
+       return Status;
+
+   InitializeObjectAttributes(&ObjectAttributes,
+                              &DeviceParametersU,
+                              OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+                              InstanceKey,
+                              NULL);
+   Status = ZwCreateKey(&DeviceParametersKey,
+                        DesiredAccess,
+                        &ObjectAttributes,
+                        0,
+                        NULL,
+                        REG_OPTION_NON_VOLATILE,
+                        NULL);
+   ZwClose(InstanceKey);
+
+   if (NT_SUCCESS(Status))
+       *DeviceInterfaceKey = DeviceParametersKey;
+
+   return Status;
 }
 
 /*++
@@ -405,10 +447,11 @@ IoGetDeviceInterfaces(IN CONST GUID *InterfaceClassGuid,
     PKEY_BASIC_INFORMATION DeviceBi = NULL;
     PKEY_BASIC_INFORMATION ReferenceBi = NULL;
     PKEY_VALUE_PARTIAL_INFORMATION bip = NULL;
+    PKEY_VALUE_PARTIAL_INFORMATION PartialInfo;
     UNICODE_STRING KeyName;
     OBJECT_ATTRIBUTES ObjectAttributes;
     BOOLEAN FoundRightPDO = FALSE;
-    ULONG i = 0, j, Size;
+    ULONG i = 0, j, Size, NeededLength, ActualLength, LinkedValue;
     UNICODE_STRING ReturnBuffer = { 0, 0, NULL };
     NTSTATUS Status;
 
@@ -562,7 +605,6 @@ IoGetDeviceInterfaces(IN CONST GUID *InterfaceClassGuid,
                 /* We have to check if the interface is enabled, by
                 * reading the Linked value in the Control subkey
                 */
-#if 0
                 InitializeObjectAttributes(
                     &ObjectAttributes,
                     &Control,
@@ -582,17 +624,63 @@ IoGetDeviceInterfaces(IN CONST GUID *InterfaceClassGuid,
                 }
                 else if (!NT_SUCCESS(Status))
                 {
-                    DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
+                    DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
+                    goto cleanup;
+                }
+
+                RtlInitUnicodeString(&KeyName, L"Linked");
+                Status = ZwQueryValueKey(ControlKey,
+                                         &KeyName,
+                                         KeyValuePartialInformation,
+                                         NULL,
+                                         0,
+                                         &NeededLength);
+                if (Status == STATUS_BUFFER_TOO_SMALL)
+                {
+                    ActualLength = NeededLength;
+                    PartialInfo = ExAllocatePool(NonPagedPool, ActualLength);
+                    if (!PartialInfo)
+                    {
+                        Status = STATUS_INSUFFICIENT_RESOURCES;
+                        goto cleanup;
+                    }
+
+                    Status = ZwQueryValueKey(ControlKey,
+                                             &KeyName,
+                                             KeyValuePartialInformation,
+                                             PartialInfo,
+                                             ActualLength,
+                                             &NeededLength);
+                    if (!NT_SUCCESS(Status))
+                    {
+                        DPRINT1("ZwQueryValueKey #2 failed (%x)\n", Status);
+                        ExFreePool(PartialInfo);
+                        goto cleanup;
+                    }
+
+                    if (PartialInfo->Type != REG_DWORD || PartialInfo->DataLength != sizeof(ULONG))
+                    {
+                        DPRINT1("Bad registry read\n");
+                        ExFreePool(PartialInfo);
+                        goto cleanup;
+                    }
+
+                    RtlCopyMemory(&LinkedValue,
+                                  PartialInfo->Data,
+                                  PartialInfo->DataLength);
+
+                    ExFreePool(PartialInfo);
+                    if (LinkedValue == 0)
+                    {
+                        /* This interface isn't active */
+                        goto NextReferenceString;
+                    }
+                }
+                else
+                {
+                    DPRINT1("ZwQueryValueKey #1 failed (%x)\n", Status);
                     goto cleanup;
                 }
-#endif
-                /* FIXME: Read the Linked value
-                * If it doesn't exist => ERROR
-                * If it is not a REG_DWORD or Size != sizeof(ULONG) => ERROR
-                * If its value is 0, go to NextReferenceString
-                * At the moment, do as if it is active...
-                */
-                DPRINT1("Checking if device is enabled is not implemented yet!\n");
             }
 
             /* Read the SymbolicLink string and add it into SymbolicLinkList */
@@ -671,16 +759,17 @@ IoGetDeviceInterfaces(IN CONST GUID *InterfaceClassGuid,
                 DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
                 goto cleanup;
             }
-            /* RtlAppendUnicodeStringToString added a NULL at the end of the
-            * destination string, but didn't increase the Length field.
-            * Do it for it.
-            */
-            ReturnBuffer.Length += sizeof(WCHAR);
+            /* RtlAppendUnicodeStringToString added a NULL at the end of the    
+            * destination string, but didn't increase the Length field.         
+            * Do it for it.     
+            */          
+           ReturnBuffer.Length += sizeof(WCHAR);
 
 NextReferenceString:
             ExFreePool(ReferenceBi);
             ReferenceBi = NULL;
-            ExFreePool(bip);
+            if (bip)
+                ExFreePool(bip);
             bip = NULL;
             if (ReferenceKey != INVALID_HANDLE_VALUE)
             {
@@ -717,8 +806,11 @@ NextReferenceString:
             Status = STATUS_INSUFFICIENT_RESOURCES;
             goto cleanup;
         }
-        RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
-        ExFreePool(ReturnBuffer.Buffer);
+        if (ReturnBuffer.Buffer)
+        {
+            RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
+            ExFreePool(ReturnBuffer.Buffer);
+        }
         ReturnBuffer.Buffer = NewBuffer;
     }
     ReturnBuffer.Buffer[ReturnBuffer.Length / sizeof(WCHAR)] = UNICODE_NULL;
@@ -1134,7 +1226,10 @@ IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName,
     PWCHAR EndPosition;
     NTSTATUS Status;
     LPCGUID EventGuid;
-
+    HANDLE InstanceHandle, ControlHandle;
+    UNICODE_STRING KeyName;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    ULONG LinkedValue;
 
     if (SymbolicLinkName == NULL)
         return STATUS_INVALID_PARAMETER_1;
@@ -1156,6 +1251,51 @@ IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName,
     SymLink.Buffer = SymbolicLinkName->Buffer;
     SymLink.MaximumLength = SymLink.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)SymLink.Buffer);
     DPRINT("IoSetDeviceInterfaceState('%wZ', %d)\n", SymbolicLinkName, Enable);
+
+    Status = OpenRegistryHandlesFromSymbolicLink(SymbolicLinkName,
+                                                 KEY_CREATE_SUB_KEY,
+                                                 NULL,
+                                                 NULL,
+                                                 &InstanceHandle);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    RtlInitUnicodeString(&KeyName, L"Control");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               InstanceHandle,
+                               NULL);
+    Status = ZwCreateKey(&ControlHandle,
+                         KEY_SET_VALUE,
+                         &ObjectAttributes,
+                         0,
+                         NULL,
+                         REG_OPTION_VOLATILE,
+                         NULL);
+    ZwClose(InstanceHandle);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to create the Control subkey\n");
+        return Status;
+    }
+
+    LinkedValue = (Enable ? 1 : 0);
+
+    RtlInitUnicodeString(&KeyName, L"Linked");
+    Status = ZwSetValueKey(ControlHandle,
+                           &KeyName,
+                           0,
+                           REG_DWORD,
+                           &LinkedValue,
+                           sizeof(ULONG));
+    ZwClose(ControlHandle);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to write the Linked value\n");
+        return Status;
+    }
+
     /* Get pointer to the PDO */
     Status = IoGetDeviceObjectPointer(
         &SymLink,
index ef1b789..1ab5445 100644 (file)
@@ -34,6 +34,9 @@ POBJECT_TYPE IoDriverObjectType = NULL;
 extern BOOLEAN ExpInTextModeSetup;
 extern BOOLEAN PnpSystemInit;
 
+USHORT IopGroupIndex;
+PLIST_ENTRY IopGroupTable;
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 NTSTATUS NTAPI
@@ -197,6 +200,7 @@ IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
     UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
 
     if (ExpInTextModeSetup) return;
+    if (!KeLoaderBlock) return;
     RtlUpcaseUnicodeString(ServiceName, ServiceName, FALSE);
     snprintf(TextBuffer, sizeof(TextBuffer),
             "%s%sSystem32\\Drivers\\%wZ%s\n",
@@ -434,7 +438,6 @@ IopInitializeDriverModule(
    UNICODE_STRING RegistryKey;
    PDRIVER_INITIALIZE DriverEntry;
    PDRIVER_OBJECT Driver;
-   PDEVICE_OBJECT DeviceObject;
    NTSTATUS Status;
 
    DriverEntry = ModuleObject->EntryPoint;
@@ -491,14 +494,7 @@ IopInitializeDriverModule(
    }
 
    /* Set the driver as initialized */
-   Driver->Flags |= DRVO_INITIALIZED;
-   DeviceObject = Driver->DeviceObject;
-   while (DeviceObject)
-   {
-       /* Set every device as initialized too */
-       DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-       DeviceObject = DeviceObject->NextDevice;
-   }
+   IopReadyDeviceObjects(Driver);
 
    if (PnpSystemInit) IopReinitializeDrivers();
 
@@ -880,14 +876,17 @@ VOID
 FASTCALL
 IopInitializeBootDrivers(VOID)
 {
-    PLIST_ENTRY ListHead, NextEntry;
+    PLIST_ENTRY ListHead, NextEntry, NextEntry2;
     PLDR_DATA_TABLE_ENTRY LdrEntry;
     PDEVICE_NODE DeviceNode;
     PDRIVER_OBJECT DriverObject;
     LDR_DATA_TABLE_ENTRY ModuleObject;
     NTSTATUS Status;
     UNICODE_STRING DriverName;
-
+    ULONG i, Index;
+    PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
+    HANDLE KeyHandle;
+    PBOOT_DRIVER_LIST_ENTRY BootEntry;
     DPRINT("IopInitializeBootDrivers()\n");
 
     /* Use IopRootDeviceNode for now */
@@ -931,6 +930,19 @@ IopInitializeBootDrivers(VOID)
         return;
     }
 
+    /* Get highest group order index */
+    IopGroupIndex = PpInitGetGroupOrderIndex(NULL);
+    if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
+    
+    /* Allocate the group table */
+    IopGroupTable = ExAllocatePoolWithTag(PagedPool,
+                                          IopGroupIndex * sizeof(LIST_ENTRY),
+                                          TAG_IO);
+    if (IopGroupTable == NULL) ASSERT(FALSE);
+    
+    /* Initialize the group table lists */
+    for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
+    
     /* Loop the boot modules */
     ListHead = &KeLoaderBlock->LoadOrderListHead;
     NextEntry = ListHead->Flink;
@@ -940,19 +952,83 @@ IopInitializeBootDrivers(VOID)
         LdrEntry = CONTAINING_RECORD(NextEntry,
                                      LDR_DATA_TABLE_ENTRY,
                                      InLoadOrderLinks);
-
-        /*
-         * HACK: Make sure we're loading a driver
-         * (we should be using BootDriverListHead!)
-         */
-        if (wcsstr(_wcsupr(LdrEntry->BaseDllName.Buffer), L".SYS"))
+                                     
+        /* Check if the DLL needs to be initialized */
+        if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
         {
-            /* Make sure we didn't load this driver already */
-            if (!(LdrEntry->Flags & LDRP_ENTRY_INSERTED))
+            /* Call its entrypoint */
+            MmCallDllInitialize(LdrEntry, NULL);
+        }
+        
+        /* Go to the next driver */
+        NextEntry = NextEntry->Flink;
+    }
+    
+    /* Loop the boot drivers */
+    ListHead = &KeLoaderBlock->BootDriverListHead;
+    NextEntry = ListHead->Flink;
+    while (ListHead != NextEntry)
+    {
+        /* Get the entry */
+        BootEntry = CONTAINING_RECORD(NextEntry,
+                                      BOOT_DRIVER_LIST_ENTRY,
+                                      Link);
+        
+        /* Get the driver loader entry */
+        LdrEntry = BootEntry->LdrEntry;
+        
+        /* Allocate our internal accounting structure */
+        DriverInfo = ExAllocatePoolWithTag(PagedPool,
+                                           sizeof(DRIVER_INFORMATION),
+                                           TAG_IO);
+        if (DriverInfo)
+        {
+            /* Zero it and initialize it */
+            RtlZeroMemory(DriverInfo, sizeof(DRIVER_INFORMATION));
+            InitializeListHead(&DriverInfo->Link);
+            DriverInfo->DataTableEntry = BootEntry;
+            
+            /* Open the registry key */
+            Status = IopOpenRegistryKeyEx(&KeyHandle,
+                                          NULL,
+                                          &BootEntry->RegistryPath,
+                                          KEY_READ);
+            if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
+                ((KeLoaderBlock->SetupLdrBlock) && (KeyHandle = (PVOID)1)))
             {
-                DPRINT("Initializing bootdriver %wZ\n", &LdrEntry->BaseDllName);
-                /* Initialize it */
-                IopInitializeBuiltinDriver(LdrEntry);
+                /* Save the handle */
+                DriverInfo->ServiceHandle = KeyHandle;
+                
+                /* Get the group oder index */
+                Index = PpInitGetGroupOrderIndex(KeyHandle);
+                
+                /* Get the tag position */
+                DriverInfo->TagPosition = PipGetDriverTagPriority(KeyHandle);
+                
+                /* Insert it into the list, at the right place */
+                ASSERT(Index < IopGroupIndex);
+                NextEntry2 = IopGroupTable[Index].Flink;
+                while (NextEntry2 != &IopGroupTable[Index])
+                {
+                    /* Get the driver info */
+                    DriverInfoTag = CONTAINING_RECORD(NextEntry2,
+                                                      DRIVER_INFORMATION,
+                                                      Link);
+                    
+                    /* Check if we found the right tag position */
+                    if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
+                    {
+                        /* We're done */
+                        break;
+                    }
+                    
+                    /* Next entry */
+                    NextEntry2 = NextEntry2->Flink;
+                }
+                
+                /* Insert us right before the next entry */
+                NextEntry2 = NextEntry2->Blink;
+                InsertHeadList(NextEntry2, &DriverInfo->Link);
             }
         }
 
@@ -960,10 +1036,65 @@ IopInitializeBootDrivers(VOID)
         NextEntry = NextEntry->Flink;
     }
 
+    /* Loop each group index */
+    for (i = 0; i < IopGroupIndex; i++)
+    {
+        /* Loop each group table */
+        NextEntry = IopGroupTable[i].Flink;
+        while (NextEntry != &IopGroupTable[i])
+        {
+            /* Get the entry */
+            DriverInfo = CONTAINING_RECORD(NextEntry,
+                                           DRIVER_INFORMATION,
+                                           Link);
+            
+            /* Get the driver loader entry */
+            LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
+            
+            /* Initialize it */
+            IopInitializeBuiltinDriver(LdrEntry);
+            
+            /* Next entry */
+            NextEntry = NextEntry->Flink;
+        }
+    }
+    
     /* In old ROS, the loader list became empty after this point. Simulate. */
     InitializeListHead(&KeLoaderBlock->LoadOrderListHead);
 }
 
+VOID
+FASTCALL
+IopInitializeSystemDrivers(VOID)
+{
+    PUNICODE_STRING *DriverList, *SavedList;
+    
+    /* No system drivers on the boot cd */
+    if (KeLoaderBlock->SetupLdrBlock) return;
+    
+    /* Get the driver list */
+    SavedList = DriverList = CmGetSystemDriverList();
+    ASSERT(DriverList);
+    
+    /* Loop it */
+    while (*DriverList)
+    {
+        /* Load the driver */
+        ZwLoadDriver(*DriverList);
+        
+        /* Free the entry */
+        RtlFreeUnicodeString(*DriverList);
+        ExFreePool(*DriverList);
+        
+        /* Next entry */
+        InbvIndicateProgress();
+        DriverList++;
+    }
+
+    /* Free the list */
+    ExFreePool(SavedList);
+}
+
 /*
  * IopUnloadDriver
  *
@@ -1685,6 +1816,8 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams)
       cur--;
    }
 
+   IopDisplayLoadingMessage(&ServiceName);
+
    /*
     * Get service type.
     */
diff --git a/ntoskrnl/io/iomgr/drvrlist.c b/ntoskrnl/io/iomgr/drvrlist.c
deleted file mode 100644 (file)
index e15aab2..0000000
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * PROJECT:         ReactOS Kernel
- * LICENSE:         GPL - See COPYING in the top level directory
- * FILE:            ntoskrnl/io/iomgr/drvrlist.c
- * PURPOSE:         Driver List support for Grouping, Tagging, Sorting, etc.
- * PROGRAMMERS:     <UNKNOWN>
- */
-
-/* INCLUDES *******************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-
-typedef struct _SERVICE_GROUP
-{
-  LIST_ENTRY GroupListEntry;
-  UNICODE_STRING GroupName;
-  BOOLEAN ServicesRunning;
-  ULONG TagCount;
-  PULONG TagArray;
-} SERVICE_GROUP, *PSERVICE_GROUP;
-
-typedef struct _SERVICE
-{
-  LIST_ENTRY ServiceListEntry;
-  UNICODE_STRING ServiceName;
-  UNICODE_STRING RegistryPath;
-  UNICODE_STRING ServiceGroup;
-  UNICODE_STRING ImagePath;
-
-  ULONG Start;
-  ULONG Type;
-  ULONG ErrorControl;
-  ULONG Tag;
-
-/*  BOOLEAN ServiceRunning;*/  // needed ??
-} SERVICE, *PSERVICE;
-
-#define TAG_RTLREGISTRY 'vrqR'
-
-/* GLOBALS ********************************************************************/
-
-LIST_ENTRY GroupListHead = {NULL, NULL};
-LIST_ENTRY ServiceListHead  = {NULL, NULL};
-extern BOOLEAN NoGuiBoot;
-
-VOID
-FASTCALL
-INIT_FUNCTION
-IopDisplayLoadingMessage(PUNICODE_STRING ServiceName);
-
-/* PRIVATE FUNCTIONS **********************************************************/
-
-static NTSTATUS NTAPI
-IopGetGroupOrderList(PWSTR ValueName,
-                    ULONG ValueType,
-                    PVOID ValueData,
-                    ULONG ValueLength,
-                    PVOID Context,
-                    PVOID EntryContext)
-{
-  PSERVICE_GROUP Group;
-
-  DPRINT("IopGetGroupOrderList(%S, %x, 0x%p, %x, 0x%p, 0x%p)\n",
-         ValueName, ValueType, ValueData, ValueLength, Context, EntryContext);
-
-  if (ValueType == REG_BINARY &&
-      ValueData != NULL &&
-      ValueLength >= sizeof(ULONG) &&
-      ValueLength >= (*(PULONG)ValueData + 1) * sizeof(ULONG))
-    {
-      Group = (PSERVICE_GROUP)Context;
-      Group->TagCount = ((PULONG)ValueData)[0];
-      if (Group->TagCount > 0)
-        {
-         if (ValueLength >= (Group->TagCount + 1) * sizeof(ULONG))
-            {
-              Group->TagArray = ExAllocatePool(NonPagedPool, Group->TagCount * sizeof(ULONG));
-             if (Group->TagArray == NULL)
-               {
-                 Group->TagCount = 0;
-                 return STATUS_INSUFFICIENT_RESOURCES;
-               }
-             memcpy(Group->TagArray, (PULONG)ValueData + 1, Group->TagCount * sizeof(ULONG));
-           }
-         else
-           {
-             Group->TagCount = 0;
-             return STATUS_UNSUCCESSFUL;
-           }
-       }
-    }
-  return STATUS_SUCCESS;
-}
-
-static NTSTATUS NTAPI
-IopCreateGroupListEntry(PWSTR ValueName,
-                       ULONG ValueType,
-                       PVOID ValueData,
-                       ULONG ValueLength,
-                       PVOID Context,
-                       PVOID EntryContext)
-{
-  PSERVICE_GROUP Group;
-  RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-  NTSTATUS Status;
-
-
-  if (ValueType == REG_SZ)
-    {
-      DPRINT("GroupName: '%S'\n", (PWCHAR)ValueData);
-
-      Group = ExAllocatePool(NonPagedPool,
-                            sizeof(SERVICE_GROUP));
-      if (Group == NULL)
-       {
-         return(STATUS_INSUFFICIENT_RESOURCES);
-       }
-
-      RtlZeroMemory(Group, sizeof(SERVICE_GROUP));
-
-      if (!RtlCreateUnicodeString(&Group->GroupName, (PWSTR)ValueData))
-       {
-         ExFreePool(Group);
-         return(STATUS_INSUFFICIENT_RESOURCES);
-       }
-
-      RtlZeroMemory(&QueryTable, sizeof(QueryTable));
-      QueryTable[0].Name = (PWSTR)ValueData;
-      QueryTable[0].QueryRoutine = IopGetGroupOrderList;
-
-      Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
-                                     L"GroupOrderList",
-                                     QueryTable,
-                                     (PVOID)Group,
-                                     NULL);
-      DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData);
-
-      InsertTailList(&GroupListHead,
-                    &Group->GroupListEntry);
-    }
-
-  return(STATUS_SUCCESS);
-}
-
-
-static NTSTATUS NTAPI
-IopCreateServiceListEntry(PUNICODE_STRING ServiceName)
-{
-  RTL_QUERY_REGISTRY_TABLE QueryTable[7];
-  PSERVICE Service;
-  NTSTATUS Status;
-  ULONG DefaultTag = MAXULONG;
-
-  DPRINT("ServiceName: '%wZ'\n", ServiceName);
-
-  /* Allocate service entry */
-  Service = (PSERVICE)ExAllocatePool(NonPagedPool, sizeof(SERVICE));
-  if (Service == NULL)
-    {
-      DPRINT1("ExAllocatePool() failed\n");
-      return(STATUS_INSUFFICIENT_RESOURCES);
-    }
-  RtlZeroMemory(Service, sizeof(SERVICE));
-
-  /* Get service data */
-  RtlZeroMemory(&QueryTable,
-               sizeof(QueryTable));
-
-  QueryTable[0].Name = L"Start";
-  QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
-  QueryTable[0].EntryContext = &Service->Start;
-
-  QueryTable[1].Name = L"Type";
-  QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
-  QueryTable[1].EntryContext = &Service->Type;
-
-  QueryTable[2].Name = L"ErrorControl";
-  QueryTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
-  QueryTable[2].EntryContext = &Service->ErrorControl;
-
-  QueryTable[3].Name = L"Group";
-  QueryTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
-  QueryTable[3].EntryContext = &Service->ServiceGroup;
-
-  QueryTable[4].Name = L"ImagePath";
-  QueryTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT;
-  QueryTable[4].EntryContext = &Service->ImagePath;
-
-  QueryTable[5].Name = L"Tag";
-  QueryTable[5].Flags = RTL_QUERY_REGISTRY_DIRECT;
-  QueryTable[5].EntryContext = &Service->Tag;
-  QueryTable[5].DefaultData = &DefaultTag;
-  QueryTable[5].DefaultType = REG_DWORD;
-  QueryTable[5].DefaultLength = sizeof(DefaultTag);
-
-  Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
-                                 ServiceName->Buffer,
-                                 QueryTable,
-                                 NULL,
-                                 NULL);
-  if (!NT_SUCCESS(Status) || Service->Start > 1)
-    {
-      /*
-       * If something goes wrong during RtlQueryRegistryValues
-       * it'll just drop everything on the floor and return,
-       * so you have to check if the buffers were filled.
-       * Luckily we zerofilled the Service.
-       */
-      if (Service->ServiceGroup.Buffer)
-        {
-          ExFreePoolWithTag(Service->ServiceGroup.Buffer, TAG_RTLREGISTRY);
-        }
-      if (Service->ImagePath.Buffer)
-        {
-          ExFreePoolWithTag(Service->ImagePath.Buffer, TAG_RTLREGISTRY);
-        }
-      ExFreePool(Service);
-      return(Status);
-    }
-
-  /* Copy service name */
-  Service->ServiceName.Length = ServiceName->Length;
-  Service->ServiceName.MaximumLength = ServiceName->Length + sizeof(WCHAR);
-  Service->ServiceName.Buffer = ExAllocatePool(NonPagedPool,
-                                              Service->ServiceName.MaximumLength);
-  RtlCopyMemory(Service->ServiceName.Buffer,
-               ServiceName->Buffer,
-               ServiceName->Length);
-  Service->ServiceName.Buffer[ServiceName->Length / sizeof(WCHAR)] = 0;
-
-  /* Build registry path */
-  Service->RegistryPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
-  Service->RegistryPath.Buffer = ExAllocatePool(NonPagedPool,
-                                               MAX_PATH * sizeof(WCHAR));
-  wcscpy(Service->RegistryPath.Buffer,
-        L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
-  wcscat(Service->RegistryPath.Buffer,
-        Service->ServiceName.Buffer);
-  Service->RegistryPath.Length = wcslen(Service->RegistryPath.Buffer) * sizeof(WCHAR);
-
-  DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName);
-  DPRINT("RegistryPath: '%wZ'\n", &Service->RegistryPath);
-  DPRINT("ServiceGroup: '%wZ'\n", &Service->ServiceGroup);
-  DPRINT("ImagePath: '%wZ'\n", &Service->ImagePath);
-  DPRINT("Start %lx  Type %lx  Tag %lx ErrorControl %lx\n",
-        Service->Start, Service->Type, Service->Tag, Service->ErrorControl);
-
-  /* Append service entry */
-  InsertTailList(&ServiceListHead,
-                &Service->ServiceListEntry);
-
-  return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS INIT_FUNCTION
-IoCreateDriverList(VOID)
-{
-  RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-  PKEY_BASIC_INFORMATION KeyInfo = NULL;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING ServicesKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services");
-  UNICODE_STRING SubKeyName;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
-  ULONG Index;
-
-  ULONG KeyInfoLength = 0;
-  ULONG ReturnedLength;
-
-  DPRINT("IoCreateDriverList() called\n");
-
-  /* Initialize basic variables */
-  InitializeListHead(&GroupListHead);
-  InitializeListHead(&ServiceListHead);
-
-  /* Build group order list */
-  RtlZeroMemory(&QueryTable,
-               sizeof(QueryTable));
-
-  QueryTable[0].Name = L"List";
-  QueryTable[0].QueryRoutine = IopCreateGroupListEntry;
-
-  Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
-                                 L"ServiceGroupOrder",
-                                 QueryTable,
-                                 NULL,
-                                 NULL);
-  if (!NT_SUCCESS(Status))
-    return(Status);
-
-  /* Enumerate services and create the service list */
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &ServicesKeyName,
-                            OBJ_CASE_INSENSITIVE,
-                            NULL,
-                            NULL);
-
-  Status = ZwOpenKey(&KeyHandle,
-                    KEY_ENUMERATE_SUB_KEYS,
-                    &ObjectAttributes);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
-    }
-
-  KeyInfoLength = sizeof(KEY_BASIC_INFORMATION) + MAX_PATH * sizeof(WCHAR);
-  KeyInfo = ExAllocatePool(NonPagedPool, KeyInfoLength);
-  if (KeyInfo == NULL)
-    {
-      ZwClose(KeyHandle);
-      return(STATUS_INSUFFICIENT_RESOURCES);
-    }
-
-  Index = 0;
-  while (TRUE)
-    {
-      Status = ZwEnumerateKey(KeyHandle,
-                             Index,
-                             KeyBasicInformation,
-                             KeyInfo,
-                             KeyInfoLength,
-                             &ReturnedLength);
-      if (NT_SUCCESS(Status))
-       {
-         if (KeyInfo->NameLength < MAX_PATH * sizeof(WCHAR))
-           {
-
-             SubKeyName.Length = (USHORT)KeyInfo->NameLength;
-             SubKeyName.MaximumLength = (USHORT)KeyInfo->NameLength + sizeof(WCHAR);
-             SubKeyName.Buffer = KeyInfo->Name;
-             SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = 0;
-
-             DPRINT("KeyName: '%wZ'\n", &SubKeyName);
-             IopCreateServiceListEntry(&SubKeyName);
-           }
-       }
-
-      if (!NT_SUCCESS(Status))
-       break;
-
-      Index++;
-    }
-
-  ExFreePool(KeyInfo);
-  ZwClose(KeyHandle);
-
-  DPRINT("IoCreateDriverList() done\n");
-
-  return(STATUS_SUCCESS);
-}
-
-NTSTATUS INIT_FUNCTION
-IoDestroyDriverList(VOID)
-{
-    PSERVICE_GROUP CurrentGroup;
-    PSERVICE CurrentService;
-    PLIST_ENTRY NextEntry, TempEntry;
-
-    DPRINT("IoDestroyDriverList() called\n");
-
-    /* Destroy the Group List */
-    for (NextEntry = GroupListHead.Flink, TempEntry = NextEntry->Flink;
-         NextEntry != &GroupListHead;
-         NextEntry = TempEntry, TempEntry = NextEntry->Flink)
-    {
-        /* Get the entry */
-        CurrentGroup = CONTAINING_RECORD(NextEntry,
-                                         SERVICE_GROUP,
-                                         GroupListEntry);
-
-        /* Remove it from the list */
-        RemoveEntryList(&CurrentGroup->GroupListEntry);
-
-        /* Free buffers */
-        ExFreePool(CurrentGroup->GroupName.Buffer);
-        if (CurrentGroup->TagArray)
-            ExFreePool(CurrentGroup->TagArray);
-        ExFreePool(CurrentGroup);
-    }
-
-    /* Destroy the Service List */
-    for (NextEntry = ServiceListHead.Flink, TempEntry = NextEntry->Flink;
-         NextEntry != &ServiceListHead;
-         NextEntry = TempEntry, TempEntry = NextEntry->Flink)
-    {
-        /* Get the entry */
-        CurrentService = CONTAINING_RECORD(NextEntry,
-                                           SERVICE,
-                                           ServiceListEntry);
-
-        /* Remove it from the list */
-        RemoveEntryList(&CurrentService->ServiceListEntry);
-
-        /* Free buffers */
-        ExFreePool(CurrentService->ServiceName.Buffer);
-        ExFreePool(CurrentService->RegistryPath.Buffer);
-        if (CurrentService->ServiceGroup.Buffer)
-            ExFreePool(CurrentService->ServiceGroup.Buffer);
-        if (CurrentService->ImagePath.Buffer)
-            ExFreePool(CurrentService->ImagePath.Buffer);
-        ExFreePool(CurrentService);
-    }
-
-    DPRINT("IoDestroyDriverList() done\n");
-
-    /* Return success */
-    return STATUS_SUCCESS;
-}
-
-static INIT_FUNCTION NTSTATUS
-IopLoadDriver(PSERVICE Service)
-{
-   NTSTATUS Status = STATUS_UNSUCCESSFUL;
-   PUNICODE_STRING ImagePath = &Service->ImagePath;
-   PWCHAR ImageName;
-   UNICODE_STRING ImageNameU;
-
-   ImageName = wcsrchr(ImagePath->Buffer, L'\\');
-   if (!ImageName)
-       ImageName = ImagePath->Buffer;
-   else
-       ImageName++;
-
-   RtlInitUnicodeString(&ImageNameU, ImageName);
-
-   IopDisplayLoadingMessage(&ImageNameU);
-
-   Status = ZwLoadDriver(&Service->RegistryPath);
-   IopBootLog(&Service->ImagePath, NT_SUCCESS(Status) ? TRUE : FALSE);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("IopLoadDriver() failed (Status %lx)\n", Status);
-#if 0
-      if (Service->ErrorControl == 1)
-      {
-         /* Log error */
-      }
-      else if (Service->ErrorControl == 2)
-      {
-         if (IsLastKnownGood == FALSE)
-         {
-            /* Boot last known good configuration */
-         }
-      }
-      else if (Service->ErrorControl == 3)
-      {
-         if (IsLastKnownGood == FALSE)
-         {
-            /* Boot last known good configuration */
-         }
-         else
-         {
-            /* BSOD! */
-         }
-      }
-#endif
-   }
-   return Status;
-}
-
-/*
- * IopInitializeSystemDrivers
- *
- * Load drivers marked as system start.
- *
- * Parameters
- *    None
- *
- * Return Value
- *    None
- */
-VOID
-FASTCALL
-IopInitializeSystemDrivers(VOID)
-{
-   PSERVICE_GROUP CurrentGroup;
-   PSERVICE CurrentService;
-   NTSTATUS Status;
-   ULONG i;
-   PLIST_ENTRY NextGroupEntry, NextServiceEntry;
-
-   DPRINT("IopInitializeSystemDrivers()\n");
-
-    /* Start looping */
-    for (NextGroupEntry = GroupListHead.Flink;
-         NextGroupEntry != &GroupListHead;
-         NextGroupEntry = NextGroupEntry->Flink)
-    {
-        /* Get the entry */
-        CurrentGroup = CONTAINING_RECORD(NextGroupEntry,
-                                         SERVICE_GROUP,
-                                         GroupListEntry);
-
-        DPRINT("Group: %wZ\n", &CurrentGroup->GroupName);
-
-        /* Load all drivers with a valid tag */
-        for (i = 0; i < CurrentGroup->TagCount; i++)
-        {
-            /* Start looping */
-            for (NextServiceEntry = ServiceListHead.Flink;
-                 NextServiceEntry != &ServiceListHead;
-                 NextServiceEntry = NextServiceEntry->Flink)
-            {
-                /* Get the entry */
-                CurrentService = CONTAINING_RECORD(NextServiceEntry,
-                                                   SERVICE,
-                                                   ServiceListEntry);
-
-                if ((!RtlCompareUnicodeString(&CurrentGroup->GroupName,
-                                             &CurrentService->ServiceGroup,
-                                             TRUE)) &&
-                       (CurrentService->Start == SERVICE_SYSTEM_START) &&
-                           (CurrentService->Tag == CurrentGroup->TagArray[i]))
-
-                {
-                    DPRINT("  Path: %wZ\n", &CurrentService->RegistryPath);
-                    Status = IopLoadDriver(CurrentService);
-                    InbvIndicateProgress();
-                }
-            }
-        }
-
-        /* Load all drivers without a tag or with an invalid tag */
-        for (NextServiceEntry = ServiceListHead.Flink;
-             NextServiceEntry != &ServiceListHead;
-             NextServiceEntry = NextServiceEntry->Flink)
-        {
-            /* Get the entry */
-            CurrentService = CONTAINING_RECORD(NextServiceEntry,
-                                               SERVICE,
-                                               ServiceListEntry);
-
-            if ((!RtlCompareUnicodeString(&CurrentGroup->GroupName,
-                                         &CurrentService->ServiceGroup,
-                                         TRUE)) &&
-                   (CurrentService->Start == SERVICE_SYSTEM_START))
-            {
-                for (i = 0; i < CurrentGroup->TagCount; i++)
-                {
-                    if (CurrentGroup->TagArray[i] == CurrentService->Tag)
-                    {
-                        break;
-                    }
-                }
-
-                if (i >= CurrentGroup->TagCount)
-                {
-                    DPRINT("  Path: %wZ\n", &CurrentService->RegistryPath);
-                    Status = IopLoadDriver(CurrentService);
-                    InbvIndicateProgress();
-                }
-                
-            }
-        }
-    }
-
-    DPRINT("IopInitializeSystemDrivers() done\n");
-}
index cb32297..a0f16bb 100644 (file)
@@ -488,10 +488,7 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     if (!IopCreateRootDirectories()) return FALSE;
 
     /* Initialize PnP manager */
-    PnpInit();
-
-    /* Create the group driver list */
-    IoCreateDriverList();
+    IopInitializePlugPlayServices();
 
     /* Load boot start drivers */
     IopInitializeBootDrivers();
@@ -530,9 +527,6 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     IopInitializeSystemDrivers();
     PnpSystemInit = TRUE;
 
-    /* Destroy the group driver list */
-    IoDestroyDriverList();
-
     /* Reinitialize drivers that requested it */
     IopReinitializeDrivers();
 
diff --git a/ntoskrnl/io/pnpmgr/pnpinit.c b/ntoskrnl/io/pnpmgr/pnpinit.c
new file mode 100644 (file)
index 0000000..deced32
--- /dev/null
@@ -0,0 +1,502 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            ntoskrnl/io/pnpmgr/pnpinit.c
+ * PURPOSE:         PnP Initialization Code
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+typedef struct _IOPNP_DEVICE_EXTENSION
+{
+    PWCHAR CompatibleIdList;
+    ULONG CompatibleIdListSize;
+} IOPNP_DEVICE_EXTENSION, *PIOPNP_DEVICE_EXTENSION;
+
+PUNICODE_STRING PiInitGroupOrderTable;
+ULONG PiInitGroupOrderTableCount;
+INTERFACE_TYPE PnpDefaultInterfaceType;
+
+/* FUNCTIONS ******************************************************************/
+
+INTERFACE_TYPE
+NTAPI
+IopDetermineDefaultInterfaceType(VOID)
+{
+    /* FIXME: ReactOS doesn't support MicroChannel yet */
+    return Isa;
+}
+
+NTSTATUS
+NTAPI
+IopInitializeArbiters(VOID)
+{
+     /* FIXME: TODO */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+PiInitCacheGroupInformation(VOID)
+{
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+    PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
+    PUNICODE_STRING GroupTable;
+    ULONG Count;
+    UNICODE_STRING GroupString =
+        RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet"
+                            L"\\Control\\ServiceGroupOrder");
+    
+    /* ReactOS HACK for SETUPLDR */
+    if (KeLoaderBlock->SetupLdrBlock)
+    {
+        /* Bogus data */
+        PiInitGroupOrderTableCount = 0;
+        PiInitGroupOrderTable = (PVOID)0xBABEB00B;
+        return STATUS_SUCCESS;
+    }
+    
+    /* Open the registry key */
+    Status = IopOpenRegistryKeyEx(&KeyHandle,
+                                  NULL,
+                                  &GroupString,
+                                  KEY_READ);
+    if (NT_SUCCESS(Status))
+    {
+        /* Get the list */
+        Status = IopGetRegistryValue(KeyHandle, L"List", &KeyValueInformation);
+        ZwClose(KeyHandle);
+        
+        /* Make sure we got it */
+        if (NT_SUCCESS(Status))
+        {
+            /* Make sure it's valid */
+            if ((KeyValueInformation->Type == REG_MULTI_SZ) &&
+                (KeyValueInformation->DataLength))
+            {
+                /* Convert it to unicode strings */
+                Status = PnpRegMultiSzToUnicodeStrings(KeyValueInformation,
+                                                       &GroupTable,
+                                                       &Count);
+                
+                /* Cache it for later */
+                PiInitGroupOrderTable = GroupTable;
+                PiInitGroupOrderTableCount = Count;
+            }
+            else
+            {
+                /* Fail */
+                Status = STATUS_UNSUCCESSFUL;
+            }
+            
+            /* Free the information */
+            ExFreePool(KeyValueInformation);
+        }
+    }
+    
+    /* Return status */
+    return Status;
+}
+
+USHORT
+NTAPI
+PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle)
+{
+    NTSTATUS Status;
+    PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
+    ULONG i;
+    PVOID Buffer;
+    UNICODE_STRING Group;
+    PAGED_CODE();
+       
+    /* Make sure we have a cache */
+    if (!PiInitGroupOrderTable) return -1;
+    
+    /* If we don't have a handle, the rest is easy -- return the count */
+    if (!ServiceHandle) return PiInitGroupOrderTableCount + 1;
+    
+    /* Otherwise, get the group value */
+    Status = IopGetRegistryValue(ServiceHandle, L"Group", &KeyValueInformation);
+    if (!NT_SUCCESS(Status)) return PiInitGroupOrderTableCount;
+
+    /* Make sure we have a valid string */
+    ASSERT(KeyValueInformation->Type == REG_SZ);
+    ASSERT(KeyValueInformation->DataLength);
+    
+    /* Convert to unicode string */
+    Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset);
+    PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &Group.Length);
+    Group.MaximumLength = KeyValueInformation->DataLength;
+    Group.Buffer = Buffer;
+    
+    /* Loop the groups */
+    for (i = 0; i < PiInitGroupOrderTableCount; i++)
+    {
+        /* Try to find a match */
+        if (RtlEqualUnicodeString(&Group, &PiInitGroupOrderTable[i], TRUE)) break;
+    }
+    
+    /* We're done */
+    ExFreePool(KeyValueInformation);
+    return i;
+}
+
+USHORT
+NTAPI
+PipGetDriverTagPriority(IN HANDLE ServiceHandle)
+{
+    NTSTATUS Status;
+    HANDLE KeyHandle = NULL;
+    PKEY_VALUE_FULL_INFORMATION KeyValueInformation = NULL;
+    PKEY_VALUE_FULL_INFORMATION KeyValueInformationTag;
+    PKEY_VALUE_FULL_INFORMATION KeyValueInformationGroupOrderList;
+    PVOID Buffer;
+    UNICODE_STRING Group;
+    PULONG GroupOrder;
+    ULONG i = -1, Count, Tag = 0;
+    UNICODE_STRING GroupString =
+    RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet"
+                        L"\\Control\\ServiceGroupOrder");
+    
+    /* Open the key */
+    Status = IopOpenRegistryKeyEx(&KeyHandle, NULL, &GroupString, KEY_READ);
+    if (!NT_SUCCESS(Status)) goto Quickie;
+    
+    /* Read the group */
+    Status = IopGetRegistryValue(ServiceHandle, L"Group", &KeyValueInformation);
+    if (!NT_SUCCESS(Status)) goto Quickie;
+    
+    /* Make sure we have a group */
+    if ((KeyValueInformation->Type == REG_SZ) &&
+        (KeyValueInformation->DataLength))
+    {
+        /* Convert to unicode string */
+        Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset);
+        PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &Group.Length);
+        Group.MaximumLength = KeyValueInformation->DataLength;
+        Group.Buffer = Buffer;
+    }
+
+    /* Now read the tag */
+    Status = IopGetRegistryValue(ServiceHandle, L"Tag", &KeyValueInformationTag);
+    if (!NT_SUCCESS(Status)) goto Quickie;
+
+    /* Make sure we have a tag */
+    if ((KeyValueInformationTag->Type == REG_DWORD) &&
+        (KeyValueInformationTag->DataLength))
+    {
+        /* Read it */
+        Tag = *(PULONG)((ULONG_PTR)KeyValueInformationTag +
+                        KeyValueInformationTag->DataOffset);
+    }
+    
+    /* We can get rid of this now */
+    ExFreePool(KeyValueInformationTag);
+
+    /* Now let's read the group's tag order */
+    Status = IopGetRegistryValue(KeyHandle,
+                                 Group.Buffer,
+                                 &KeyValueInformationGroupOrderList);
+    
+    /* We can get rid of this now */
+Quickie:
+    if (KeyValueInformation) ExFreePool(KeyValueInformation);
+    if (KeyHandle) NtClose(KeyHandle);
+    if (!NT_SUCCESS(Status)) return -1;
+    
+    /* We're on the success path -- validate the tag order*/
+    if ((KeyValueInformationGroupOrderList->Type == REG_BINARY) &&
+        (KeyValueInformationGroupOrderList->DataLength))
+    {
+        /* Get the order array */
+        GroupOrder = (PULONG)((ULONG_PTR)KeyValueInformationGroupOrderList +
+                              KeyValueInformationGroupOrderList->DataOffset);
+        
+        /* Get the count */
+        Count = *GroupOrder;
+        ASSERT(((Count + 1) * sizeof(ULONG)) <=
+               KeyValueInformationGroupOrderList->DataLength);
+        
+        /* Now loop each tag */
+        GroupOrder++;
+        for (i = 1; i <= Count; i++)
+        {
+            /* If we found it, we're out */
+            if (Tag == *GroupOrder) break;
+
+            /* Try the next one */
+            GroupOrder++;
+        }
+    }
+    
+    /* Last buffer to free */
+    ExFreePool(KeyValueInformationGroupOrderList);
+    return i;
+}
+
+NTSTATUS
+NTAPI
+PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode,
+                       IN BOOLEAN LoadDriver,     
+                       IN PDRIVER_OBJECT DriverObject)
+{ 
+    NTSTATUS Status;
+    HANDLE EnumRootKey, SubKey, ControlKey, ClassKey, PropertiesKey;
+    UNICODE_STRING ClassGuid, Properties;
+    UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT);
+    UNICODE_STRING ControlClass =
+    RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class");
+    PKEY_VALUE_FULL_INFORMATION KeyValueInformation = NULL;
+    PWCHAR Buffer;
+    
+    /* Open enumeration root key */
+    Status = IopOpenRegistryKeyEx(&EnumRootKey,
+                                  NULL,
+                                  &EnumRoot,
+                                  KEY_READ);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
+        return Status;
+    }
+    
+    /* Open instance subkey */
+    Status = IopOpenRegistryKeyEx(&SubKey,
+                                  EnumRootKey,
+                                  &DeviceNode->InstancePath,
+                                  KEY_READ);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
+        ZwClose(EnumRootKey);
+        return Status;
+    }
+    
+    /* Get class GUID */
+    Status = IopGetRegistryValue(SubKey,
+                                 REGSTR_VAL_CLASSGUID,
+                                 &KeyValueInformation);
+    if (NT_SUCCESS(Status))
+    {
+        /* Convert to unicode string */
+        Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset);
+        PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &ClassGuid.Length);
+        ClassGuid.MaximumLength = KeyValueInformation->DataLength;
+        ClassGuid.Buffer = Buffer;
+        
+        /* Open the key */
+        Status = IopOpenRegistryKeyEx(&ControlKey,
+                                      NULL,
+                                      &ControlClass,
+                                      KEY_READ);
+        if (!NT_SUCCESS(Status))
+        {
+            /* No class key */
+            DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
+            ClassKey = NULL;
+        }
+        else
+        {
+            /* Open the class key */
+            Status = IopOpenRegistryKeyEx(&ClassKey,
+                                          ControlKey,
+                                          &ClassGuid,
+                                          KEY_READ);
+            ZwClose(ControlKey);
+            if (!NT_SUCCESS(Status))
+            {
+                /* No class key */
+                DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
+                ClassKey = NULL;
+            }
+        }
+        
+        /* Check if we made it till here */
+        if (ClassKey)
+        {
+            /* Get the device properties */
+            RtlInitUnicodeString(&Properties, REGSTR_KEY_DEVICE_PROPERTIES);
+            Status = IopOpenRegistryKeyEx(&PropertiesKey,
+                                          ClassKey,
+                                          &Properties,
+                                          KEY_READ);
+            if (!NT_SUCCESS(Status))
+            {
+                /* No properties */
+                DPRINT("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
+                PropertiesKey = NULL;
+            }
+        }
+        
+        /* Free the registry data */
+        ExFreePool(KeyValueInformation);
+    }
+    
+    /* Do ReactOS-style setup */
+    IopAttachFilterDrivers(DeviceNode, TRUE);
+    Status = IopInitializeDevice(DeviceNode, DriverObject);
+    if (NT_SUCCESS(Status))
+    {
+        IopAttachFilterDrivers(DeviceNode, FALSE);
+        Status = IopStartDevice(DeviceNode);
+    }
+    
+    /* Return status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+IopInitializePlugPlayServices(VOID)
+{
+    NTSTATUS Status;
+    ULONG Disposition;
+    HANDLE KeyHandle, EnumHandle, ParentHandle, TreeHandle;
+    UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET");
+    PDEVICE_OBJECT Pdo;
+    
+    /* Initialize locks and such */
+    KeInitializeSpinLock(&IopDeviceTreeLock);
+        
+    /* Get the default interface */
+    PnpDefaultInterfaceType = IopDetermineDefaultInterfaceType();
+    
+    /* Initialize arbiters */
+    Status = IopInitializeArbiters();
+    if (!NT_SUCCESS(Status)) return Status;
+    
+    /* Setup the group cache */
+    Status = PiInitCacheGroupInformation();
+    if (!NT_SUCCESS(Status)) return Status;
+    
+    /* Open the current control set */
+    Status = IopOpenRegistryKeyEx(&KeyHandle,
+                                  NULL,
+                                  &KeyName,
+                                  KEY_ALL_ACCESS);
+    if (!NT_SUCCESS(Status)) return Status;
+    
+    /* Create the enum key */
+    RtlInitUnicodeString(&KeyName, REGSTR_KEY_ENUM);
+    Status = IopCreateRegistryKeyEx(&EnumHandle,
+                                    KeyHandle,
+                                    &KeyName,
+                                    KEY_ALL_ACCESS,
+                                    REG_OPTION_NON_VOLATILE,
+                                    &Disposition);
+    if (!NT_SUCCESS(Status)) return Status;
+    
+    /* Check if it's a new key */
+    if (Disposition == REG_CREATED_NEW_KEY)
+    {
+        /* FIXME: DACLs */
+        DPRINT1("Need to build DACL\n");
+    }
+    
+    /* Create the root key */
+    ParentHandle = EnumHandle;
+    RtlInitUnicodeString(&KeyName, REGSTR_KEY_ROOTENUM);
+    Status = IopCreateRegistryKeyEx(&EnumHandle,
+                                    ParentHandle,
+                                    &KeyName,
+                                    KEY_ALL_ACCESS,
+                                    REG_OPTION_NON_VOLATILE,
+                                    &Disposition);
+    NtClose(ParentHandle);
+    if (!NT_SUCCESS(Status)) return Status;
+    NtClose(EnumHandle);
+    
+    /* Open the root key now */
+    RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\ENUM");
+    Status = IopOpenRegistryKeyEx(&EnumHandle,
+                                  NULL,
+                                  &KeyName,
+                                  KEY_ALL_ACCESS);
+    if (NT_SUCCESS(Status))
+    {
+        /* Create the root dev node */
+        RtlInitUnicodeString(&KeyName, REGSTR_VAL_ROOT_DEVNODE);
+        Status = IopCreateRegistryKeyEx(&TreeHandle,
+                                        EnumHandle,
+                                        &KeyName,
+                                        KEY_ALL_ACCESS,
+                                        REG_OPTION_NON_VOLATILE,
+                                        NULL);
+        NtClose(EnumHandle);
+        if (NT_SUCCESS(Status)) NtClose(TreeHandle);
+    }
+   
+    /* Create the root driver */
+    Status = IoCreateDriver(NULL, PnpRootDriverEntry);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("IoCreateDriverObject() failed\n");
+        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+    
+    /* Create the root PDO */
+    Status = IoCreateDevice(IopRootDriverObject,
+                            sizeof(IOPNP_DEVICE_EXTENSION),
+                            NULL,
+                            FILE_DEVICE_CONTROLLER,
+                            0,
+                            FALSE,
+                            &Pdo);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("IoCreateDevice() failed\n");
+        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+    
+    /* This is a bus enumerated device */
+    Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
+    
+    /* Create the root device node */
+    IopRootDeviceNode = PipAllocateDeviceNode(Pdo);
+
+    /* Set flags */
+    IopRootDeviceNode->Flags |= DNF_STARTED + DNF_PROCESSED + DNF_ENUMERATED +
+                                DNF_MADEUP + DNF_NO_RESOURCE_REQUIRED +
+                                DNF_ADDED;
+    
+    /* Create instance path */
+    RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath,
+                           REGSTR_VAL_ROOT_DEVNODE);
+    
+    /* Call the add device routine */
+    IopRootDriverObject->DriverExtension->AddDevice(IopRootDriverObject,
+                                                    IopRootDeviceNode->PhysicalDeviceObject);
+
+    /* Initialize PnP-Event notification support */
+    Status = IopInitPlugPlayEvents();
+    if (!NT_SUCCESS(Status)) return Status;
+    
+    /* Report the device to the user-mode pnp manager */
+    IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
+                              &IopRootDeviceNode->InstancePath);   
+    
+    /* Initialize the Bus Type GUID List */
+    PnpBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(IO_BUS_TYPE_GUID_LIST));
+    RtlZeroMemory(PnpBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST));
+    ExInitializeFastMutex(&PnpBusTypeGuidList->Lock);
+    
+    /* Launch the firmware mapper */
+    Status = IopUpdateRootKey();
+    if (!NT_SUCCESS(Status)) return Status;
+    
+    /* Close the handle to the control set */
+    NtClose(KeyHandle);
+    
+    /* We made it */
+    return STATUS_SUCCESS;
+}
+
+/* EOF */
index 4428396..645b837 100644 (file)
@@ -29,8 +29,7 @@ extern BOOLEAN PnpSystemInit;
 /* DATA **********************************************************************/
 
 PDRIVER_OBJECT IopRootDriverObject;
-FAST_MUTEX IopBusTypeGuidListLock;
-PIO_BUS_TYPE_GUID_LIST IopBusTypeGuidList = NULL;
+PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList = NULL;
 
 #if defined (ALLOC_PRAGMA)
 #pragma alloc_text(INIT, PnpInit)
@@ -45,24 +44,10 @@ typedef struct _INVALIDATE_DEVICE_RELATION_DATA
 } INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA;
 
 /* FUNCTIONS *****************************************************************/
-
-NTSTATUS
-IopAssignDeviceResources(
-   IN PDEVICE_NODE DeviceNode,
-   OUT ULONG *pRequiredSize);
-
-NTSTATUS
-IopTranslateDeviceResources(
-   IN PDEVICE_NODE DeviceNode,
-   IN ULONG RequiredSize);
-
-NTSTATUS
-IopUpdateResourceMapForPnPDevice(
-   IN PDEVICE_NODE DeviceNode);
-
 NTSTATUS
 NTAPI
 IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
+                       IN ULONG CreateOptions,
                        OUT PHANDLE Handle);
 
 PDEVICE_NODE
@@ -81,19 +66,20 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode,
    NTSTATUS Status;
 
    if (!DriverObject->DriverExtension->AddDevice)
+   {
+      DeviceNode->Flags |= DNF_LEGACY_DRIVER;
+   }
+
+   if (DeviceNode->Flags & DNF_LEGACY_DRIVER)
+   {
+      DeviceNode->Flags |= DNF_ADDED + DNF_STARTED;
       return STATUS_SUCCESS;
+   }
 
    /* This is a Plug and Play driver */
    DPRINT("Plug and Play driver found\n");
    ASSERT(DeviceNode->PhysicalDeviceObject);
 
-   /* Check if this plug-and-play driver is used as a legacy one for this device node */
-   if (IopDeviceNodeHasFlag(DeviceNode, DNF_LEGACY_DRIVER))
-   {
-      IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED);
-      return STATUS_SUCCESS;
-   }
-
    DPRINT("Calling %wZ->AddDevice(%wZ)\n",
       &DriverObject->DriverName,
       &DeviceNode->InstancePath);
@@ -133,100 +119,161 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode,
    ObDereferenceObject(Fdo);
 
    IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED);
-   IopDeviceNodeSetFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
 
    return STATUS_SUCCESS;
 }
 
+VOID
+NTAPI
+IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
+{
+    IO_STACK_LOCATION Stack;
+    PVOID Dummy;
+
+    RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
+    Stack.MajorFunction = IRP_MJ_PNP;
+    Stack.MinorFunction = IRP_MN_REMOVE_DEVICE;
+
+    /* Drivers should never fail a IRP_MN_REMOVE_DEVICE request */
+    IopSynchronousCall(DeviceObject, &Stack, &Dummy);
+}
+
+VOID
+NTAPI
+IopStartDevice2(IN PDEVICE_OBJECT DeviceObject)
+{
+    IO_STACK_LOCATION Stack;
+    PDEVICE_NODE DeviceNode;
+    NTSTATUS Status;
+    PVOID Dummy;
+    
+    /* Get the device node */
+    DeviceNode = IopGetDeviceNode(DeviceObject);
+    
+    /* Build the I/O stack locaiton */
+    RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
+    Stack.MajorFunction = IRP_MJ_PNP;
+    Stack.MinorFunction = IRP_MN_START_DEVICE;
+    
+    /* Check if we didn't already report the resources */
+    if (!(DeviceNode->Flags & DNF_RESOURCE_REPORTED))
+    {
+        /* Report them */
+        Stack.Parameters.StartDevice.AllocatedResources =
+            DeviceNode->ResourceList;
+        Stack.Parameters.StartDevice.AllocatedResourcesTranslated =
+            DeviceNode->ResourceListTranslated;
+    }
+    
+    /* I don't think we set this flag yet */
+    ASSERT(!(DeviceNode->Flags & DNF_STOPPED));
+    
+    /* Do the call */
+    Status = IopSynchronousCall(DeviceObject, &Stack, &Dummy);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Send an IRP_MN_REMOVE_DEVICE request */
+        IopSendRemoveDevice(DeviceObject);
+
+        /* Set the appropriate flag */
+        DeviceNode->Flags |= DNF_START_FAILED;
+
+        DPRINT1("Warning: PnP Start failed (%wZ)\n", &DeviceNode->InstancePath);
+        return;
+    }
+    
+    /* Otherwise, mark us as started */
+    DeviceNode->Flags |= DNF_STARTED;
+
+    /* We now need enumeration */
+    DeviceNode->Flags |= DNF_NEED_ENUMERATION_ONLY;
+}
+
+NTSTATUS
+NTAPI
+IopStartAndEnumerateDevice(IN PDEVICE_NODE DeviceNode)
+{
+    PDEVICE_OBJECT DeviceObject;
+    NTSTATUS Status;
+    PAGED_CODE();
+    
+    /* Sanity check */
+    ASSERT((DeviceNode->Flags & DNF_ADDED));
+    ASSERT((DeviceNode->Flags & (DNF_RESOURCE_ASSIGNED |
+                                 DNF_RESOURCE_REPORTED |
+                                 DNF_NO_RESOURCE_REQUIRED)));
+    ASSERT((!(DeviceNode->Flags & (DNF_HAS_PROBLEM |
+                                   DNF_STARTED |
+                                   DNF_START_REQUEST_PENDING))));
+           
+    /* Get the device object */
+    DeviceObject = DeviceNode->PhysicalDeviceObject;
+    
+    /* Check if we're not started yet */
+    if (!(DeviceNode->Flags & DNF_STARTED))
+    {
+        /* Start us */
+        IopStartDevice2(DeviceObject);
+    }
+    
+    /* Do we need to query IDs? This happens in the case of manual reporting */
+#if 0
+    if (DeviceNode->Flags & DNF_NEED_QUERY_IDS)
+    {
+        DPRINT1("Warning: Device node has DNF_NEED_QUERY_IDS\n");
+        /* And that case shouldn't happen yet */
+        ASSERT(FALSE);
+    }
+#endif
+    
+    /* Make sure we're started, and check if we need enumeration */
+    if ((DeviceNode->Flags & DNF_STARTED) &&
+        (DeviceNode->Flags & DNF_NEED_ENUMERATION_ONLY))
+    {
+        /* Enumerate us */
+        IoSynchronousInvalidateDeviceRelations(DeviceObject, BusRelations);
+        IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
+        Status = STATUS_SUCCESS;
+    }
+    else
+    {
+        /* Nothing to do */
+        Status = STATUS_SUCCESS;
+    }
+    
+    /* Return */
+    return Status;
+}
+
 NTSTATUS
 IopStartDevice(
    PDEVICE_NODE DeviceNode)
 {
-   IO_STATUS_BLOCK IoStatusBlock;
-   IO_STACK_LOCATION Stack;
-   ULONG RequiredLength;
    NTSTATUS Status;
-   HANDLE InstanceHandle, ControlHandle;
+   HANDLE InstanceHandle = INVALID_HANDLE_VALUE, ControlHandle = INVALID_HANDLE_VALUE;
    UNICODE_STRING KeyName;
    OBJECT_ATTRIBUTES ObjectAttributes;
 
-   IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
-   DPRINT("Sending IRP_MN_FILTER_RESOURCE_REQUIREMENTS to device stack\n");
-   Stack.Parameters.FilterResourceRequirements.IoResourceRequirementList = DeviceNode->ResourceRequirements;
-   Status = IopInitiatePnpIrp(
-      DeviceNode->PhysicalDeviceObject,
-      &IoStatusBlock,
-      IRP_MN_FILTER_RESOURCE_REQUIREMENTS,
-      &Stack);
-   if (!NT_SUCCESS(Status) && Status != STATUS_NOT_SUPPORTED)
-   {
-      DPRINT("IopInitiatePnpIrp(IRP_MN_FILTER_RESOURCE_REQUIREMENTS) failed\n");
-      return Status;
-   }
-   DeviceNode->ResourceRequirements = (PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information;
-
-   Status = IopAssignDeviceResources(DeviceNode, &RequiredLength);
-   if (NT_SUCCESS(Status))
-   {
-      Status = IopTranslateDeviceResources(DeviceNode, RequiredLength);
-      if (NT_SUCCESS(Status))
-      {
-         Status = IopUpdateResourceMapForPnPDevice(DeviceNode);
-         if (!NT_SUCCESS(Status))
-         {
-             DPRINT("IopUpdateResourceMap() failed (Status 0x%08lx)\n", Status);
-         }
-      }
-      else
-      {
-         DPRINT("IopTranslateDeviceResources() failed (Status 0x%08lx)\n", Status);
-      }
-   }
-   else
+   if (DeviceNode->Flags & (DNF_STARTED | DNF_START_REQUEST_PENDING))
    {
-      DPRINT("IopAssignDeviceResources() failed (Status 0x%08lx)\n", Status);
+       /* Nothing to do here */
+       return STATUS_SUCCESS;
    }
-   IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
-
-   DPRINT("Sending IRP_MN_START_DEVICE to driver\n");
-   Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList;
-   Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->ResourceListTranslated;
-
-   /*
-    * Windows NT Drivers receive IRP_MN_START_DEVICE in a critical region and
-    * actually _depend_ on this!. This is because NT will lock the Device Node
-    * with an ERESOURCE, which of course requires APCs to be disabled.
-    */
-   KeEnterCriticalRegion();
-
-   Status = IopInitiatePnpIrp(
-      DeviceNode->PhysicalDeviceObject,
-      &IoStatusBlock,
-      IRP_MN_START_DEVICE,
-      &Stack);
-
-   KeLeaveCriticalRegion();
 
+   Status = IopAssignDeviceResources(DeviceNode);
    if (!NT_SUCCESS(Status))
-   {
-      DPRINT("IopInitiatePnpIrp() failed\n");
-   }
-   else
-   {
-      if (IopDeviceNodeHasFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY))
-      {
-         DPRINT("Device needs enumeration, invalidating bus relations\n");
-         /* Invalidate device relations synchronously
-            (otherwise there will be dirty read of DeviceNode) */
-         IopEnumerateDevice(DeviceNode->PhysicalDeviceObject);
-         IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
-      }
-   }
+       goto ByeBye;
+
+   /* New PnP ABI */
+   IopStartAndEnumerateDevice(DeviceNode);
 
-   Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, &InstanceHandle);
+   /* FIX: Should be done in new device instance code */
+   Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceHandle);
    if (!NT_SUCCESS(Status))
-       return Status;
+       goto ByeBye;
 
+   /* FIX: Should be done in IoXxxPrepareDriverLoading */
+   // {
    RtlInitUnicodeString(&KeyName, L"Control");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
@@ -235,19 +282,18 @@ IopStartDevice(
                               NULL);
    Status = ZwCreateKey(&ControlHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
    if (!NT_SUCCESS(Status))
-   {
-       ZwClose(InstanceHandle);
-       return Status;
-   }
+       goto ByeBye;
 
    RtlInitUnicodeString(&KeyName, L"ActiveService");
    Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_SZ, DeviceNode->ServiceName.Buffer, DeviceNode->ServiceName.Length);
+   // }
 
-   if (NT_SUCCESS(Status))
-       IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
+ByeBye:
+   if (ControlHandle != INVALID_HANDLE_VALUE)
+       ZwClose(ControlHandle);
 
-   ZwClose(ControlHandle);
-   ZwClose(InstanceHandle);
+   if (InstanceHandle != INVALID_HANDLE_VALUE)
+       ZwClose(InstanceHandle);
 
    return Status;
 }
@@ -320,14 +366,14 @@ IopGetBusTypeGuidIndex(LPGUID BusTypeGuid)
    PVOID NewList;
 
    /* Acquire the lock */
-   ExAcquireFastMutex(&IopBusTypeGuidListLock);
+   ExAcquireFastMutex(&PnpBusTypeGuidList->Lock);
 
    /* Loop all entries */
-   while (i < IopBusTypeGuidList->GuidCount)
+   while (i < PnpBusTypeGuidList->GuidCount)
    {
        /* Try to find a match */
        if (RtlCompareMemory(BusTypeGuid,
-                            &IopBusTypeGuidList->Guids[i],
+                            &PnpBusTypeGuidList->Guids[i],
                             sizeof(GUID)) == sizeof(GUID))
        {
            /* Found it */
@@ -338,43 +384,43 @@ IopGetBusTypeGuidIndex(LPGUID BusTypeGuid)
    }
 
    /* Check if we have to grow the list */
-   if (IopBusTypeGuidList->GuidCount)
+   if (PnpBusTypeGuidList->GuidCount)
    {
        /* Calculate the new size */
        NewSize = sizeof(IO_BUS_TYPE_GUID_LIST) +
-                (sizeof(GUID) * IopBusTypeGuidList->GuidCount);
+                (sizeof(GUID) * PnpBusTypeGuidList->GuidCount);
 
        /* Allocate the new copy */
        NewList = ExAllocatePool(PagedPool, NewSize);
 
        if (!NewList) {
           /* Fail */
-          ExFreePool(IopBusTypeGuidList);
+          ExFreePool(PnpBusTypeGuidList);
           goto Quickie;
        }
 
        /* Now copy them, decrease the size too */
        NewSize -= sizeof(GUID);
-       RtlCopyMemory(NewList, IopBusTypeGuidList, NewSize);
+       RtlCopyMemory(NewList, PnpBusTypeGuidList, NewSize);
 
        /* Free the old list */
-       ExFreePool(IopBusTypeGuidList);
+       ExFreePool(PnpBusTypeGuidList);
 
        /* Use the new buffer */
-       IopBusTypeGuidList = NewList;
+       PnpBusTypeGuidList = NewList;
    }
 
    /* Copy the new GUID */
-   RtlCopyMemory(&IopBusTypeGuidList->Guids[IopBusTypeGuidList->GuidCount],
+   RtlCopyMemory(&PnpBusTypeGuidList->Guids[PnpBusTypeGuidList->GuidCount],
                  BusTypeGuid,
                  sizeof(GUID));
 
    /* The new entry is the index */
-   FoundIndex = (USHORT)IopBusTypeGuidList->GuidCount;
-   IopBusTypeGuidList->GuidCount++;
+   FoundIndex = (USHORT)PnpBusTypeGuidList->GuidCount;
+   PnpBusTypeGuidList->GuidCount++;
 
 Quickie:
-   ExReleaseFastMutex(&IopBusTypeGuidListLock);
+   ExReleaseFastMutex(&PnpBusTypeGuidList->Lock);
    return FoundIndex;
 }
 
@@ -404,7 +450,13 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
    UNICODE_STRING FullServiceName;
    UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_");
    UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN");
-   HANDLE TempHandle;
+   UNICODE_STRING KeyName, ClassName;
+   PUNICODE_STRING ServiceName1;
+   ULONG LegacyValue;
+#if 0
+   UNICODE_STRING ClassGUID;
+#endif
+   HANDLE InstanceHandle;
 
    DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n",
       ParentNode, PhysicalDeviceObject, ServiceName);
@@ -418,11 +470,13 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
    RtlZeroMemory(Node, sizeof(DEVICE_NODE));
 
    if (!ServiceName)
-       ServiceName = &UnknownDeviceName;
+       ServiceName1 = &UnknownDeviceName;
+   else
+       ServiceName1 = ServiceName;
 
    if (!PhysicalDeviceObject)
    {
-      FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName->Length;
+      FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length;
       FullServiceName.Length = 0;
       FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength);
       if (!FullServiceName.Buffer)
@@ -432,7 +486,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
       }
 
       RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
-      RtlAppendUnicodeStringToString(&FullServiceName, ServiceName);
+      RtlAppendUnicodeStringToString(&FullServiceName, ServiceName1);
 
       Status = PnpRootCreateDevice(&FullServiceName, &PhysicalDeviceObject, &Node->InstancePath);
       if (!NT_SUCCESS(Status))
@@ -443,15 +497,71 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
       }
 
       /* Create the device key for legacy drivers */
-      Status = IopCreateDeviceKeyPath(&Node->InstancePath, &TempHandle);
+      Status = IopCreateDeviceKeyPath(&Node->InstancePath, REG_OPTION_VOLATILE, &InstanceHandle);
+      if (!NT_SUCCESS(Status))
+      {
+          ZwClose(InstanceHandle);
+          ExFreePool(Node);
+          ExFreePool(FullServiceName.Buffer);
+          return Status;
+      }
+
+      Node->ServiceName.Buffer = ExAllocatePool(PagedPool, ServiceName1->Length);
+      if (!Node->ServiceName.Buffer)
+      {
+          ZwClose(InstanceHandle);
+          ExFreePool(Node);
+          ExFreePool(FullServiceName.Buffer);
+          return Status;
+      }
+
+      Node->ServiceName.MaximumLength = ServiceName1->Length;
+      Node->ServiceName.Length = 0;
+
+      RtlAppendUnicodeStringToString(&Node->ServiceName, ServiceName1);
+
+      if (ServiceName)
+      {
+          RtlInitUnicodeString(&KeyName, L"Service");
+          Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName->Buffer, ServiceName->Length);
+      }
+
       if (NT_SUCCESS(Status))
-          ZwClose(TempHandle);
+      {
+          RtlInitUnicodeString(&KeyName, L"Legacy");
 
+          LegacyValue = 1;
+          Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue));
+          if (NT_SUCCESS(Status))
+          {
+              RtlInitUnicodeString(&KeyName, L"Class");
+
+              RtlInitUnicodeString(&ClassName, L"LegacyDriver");
+              Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassName.Buffer, ClassName.Length);
+#if 0
+              if (NT_SUCCESS(Status))
+              {
+                  RtlInitUnicodeString(&KeyName, L"ClassGUID");
+
+                  RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}");
+                  Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassGUID.Buffer, ClassGUID.Length);
+              }
+#endif
+          }
+      }
+
+      ZwClose(InstanceHandle);
       ExFreePool(FullServiceName.Buffer);
 
-      /* This is for drivers passed on the command line to ntoskrnl.exe */
-      IopDeviceNodeSetFlag(Node, DNF_STARTED);
+      if (!NT_SUCCESS(Status))
+      {
+          ExFreePool(Node);
+          return Status;
+      }
+
       IopDeviceNodeSetFlag(Node, DNF_LEGACY_DRIVER);
+      IopDeviceNodeSetFlag(Node, DNF_ADDED);
+      IopDeviceNodeSetFlag(Node, DNF_STARTED);
    }
 
    Node->PhysicalDeviceObject = PhysicalDeviceObject;
@@ -549,69 +659,90 @@ IopFreeDeviceNode(PDEVICE_NODE DeviceNode)
 }
 
 NTSTATUS
-IopInitiatePnpIrp(PDEVICE_OBJECT DeviceObject,
-                  PIO_STATUS_BLOCK IoStatusBlock,
-                  ULONG MinorFunction,
-                  PIO_STACK_LOCATION Stack OPTIONAL)
+NTAPI
+IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject,
+                   IN PIO_STACK_LOCATION IoStackLocation,
+                   OUT PVOID *Information)
 {
-   PDEVICE_OBJECT TopDeviceObject;
-   PIO_STACK_LOCATION IrpSp;
-   NTSTATUS Status;
-   KEVENT Event;
-   PIRP Irp;
-
-   /* Always call the top of the device stack */
-   TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
-
-   KeInitializeEvent(
-      &Event,
-      NotificationEvent,
-      FALSE);
-
-   Irp = IoBuildSynchronousFsdRequest(
-      IRP_MJ_PNP,
-      TopDeviceObject,
-      NULL,
-      0,
-      NULL,
-      &Event,
-      IoStatusBlock);
-
-   /* PNP IRPs are initialized with a status code of STATUS_NOT_SUPPORTED */
-   Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
-   Irp->IoStatus.Information = 0;
-
-   if (MinorFunction == IRP_MN_FILTER_RESOURCE_REQUIREMENTS)
-   {
-      Irp->IoStatus.Information = (ULONG_PTR)Stack->Parameters.FilterResourceRequirements.IoResourceRequirementList;
-   }
-
-   IrpSp = IoGetNextIrpStackLocation(Irp);
-   IrpSp->MinorFunction = (UCHAR)MinorFunction;
-
-   if (Stack)
-   {
-      RtlCopyMemory(&IrpSp->Parameters,
-                    &Stack->Parameters,
-                    sizeof(Stack->Parameters));
-   }
-
-   Status = IoCallDriver(TopDeviceObject, Irp);
-   if (Status == STATUS_PENDING)
-   {
-      KeWaitForSingleObject(&Event,
-                            Executive,
-                            KernelMode,
-                            FALSE,
-                            NULL);
-      Status = IoStatusBlock->Status;
-   }
-
-   ObDereferenceObject(TopDeviceObject);
-
-   return Status;
+    PIRP Irp;
+    PIO_STACK_LOCATION IrpStack;
+    IO_STATUS_BLOCK IoStatusBlock;
+    KEVENT Event;
+    NTSTATUS Status;
+    PDEVICE_OBJECT TopDeviceObject;
+    PAGED_CODE();
+    
+    /* Call the top of the device stack */
+    TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
+    
+    /* Allocate an IRP */
+    Irp = IoAllocateIrp(TopDeviceObject->StackSize, FALSE);
+    if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
+    
+    /* Initialize to failure */
+    Irp->IoStatus.Status = IoStatusBlock.Status = STATUS_NOT_SUPPORTED;
+    Irp->IoStatus.Information = IoStatusBlock.Information = 0;
+    
+    /* Initialize the event */
+    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+    
+    /* Set them up */
+    Irp->UserIosb = &IoStatusBlock;
+    Irp->UserEvent = &Event;
+    
+    /* Queue the IRP */
+    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+    IoQueueThreadIrp(Irp);
+    
+    /* Copy-in the stack */
+    IrpStack = IoGetNextIrpStackLocation(Irp);
+    *IrpStack = *IoStackLocation;
+    
+    /* Call the driver */
+    Status = IoCallDriver(TopDeviceObject, Irp);
+    if (Status == STATUS_PENDING)
+    {
+        /* Wait for it */
+        KeWaitForSingleObject(&Event,
+                              Executive,
+                              KernelMode,
+                              FALSE,
+                              NULL);
+        Status = IoStatusBlock.Status;
+    }
+    
+    /* Return the information */
+    *Information = (PVOID)IoStatusBlock.Information;
+    return Status;
 }
 
+NTSTATUS
+NTAPI
+IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject,
+                  IN OUT PIO_STATUS_BLOCK IoStatusBlock,
+                  IN ULONG MinorFunction,
+                  IN PIO_STACK_LOCATION Stack OPTIONAL)
+{
+    IO_STACK_LOCATION IoStackLocation;
+    
+    /* Fill out the stack information */
+    RtlZeroMemory(&IoStackLocation, sizeof(IO_STACK_LOCATION));
+    IoStackLocation.MajorFunction = IRP_MJ_PNP;
+    IoStackLocation.MinorFunction = MinorFunction;
+    if (Stack)
+    {
+        /* Copy the rest */
+        RtlCopyMemory(&IoStackLocation.Parameters,
+                      &Stack->Parameters,
+                      sizeof(Stack->Parameters));
+    }
+    
+    /* Do the PnP call */
+    IoStatusBlock->Status = IopSynchronousCall(DeviceObject,
+                                               &IoStackLocation,
+                                               (PVOID)&IoStatusBlock->Information);
+    return IoStatusBlock->Status;
+}
 
 NTSTATUS
 IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context)
@@ -693,6 +824,7 @@ IopTraverseDeviceTree(PDEVICETREE_TRAVERSE_CONTEXT Context)
 NTSTATUS
 NTAPI
 IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
+                       IN ULONG CreateOptions,
                        OUT PHANDLE Handle)
 {
     UNICODE_STRING EnumU = RTL_CONSTANT_STRING(ENUM_ROOT);
@@ -743,7 +875,7 @@ IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
                              &ObjectAttributes,
                              0,
                              NULL,
-                             0,
+                             CreateOptions,
                              NULL);
 
         /* Close parent key handle, we don't need it anymore */
@@ -762,918 +894,116 @@ IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
         {
             /* Yes, return success */
             *Handle = hKey;
-            return STATUS_SUCCESS;
-        }
-
-        /* Start with this new parent key */
-        hParent = hKey;
-        Current++;
-        KeyName.Buffer = (LPWSTR)Current;
-    }
-
-    return STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS
-IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2Key)
-{
-  NTSTATUS Status;
-  ULONG Disposition;
-  HANDLE PnpMgrLevel1, PnpMgrLevel2, ResourceMapKey;
-  UNICODE_STRING KeyName;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-
-  RtlInitUnicodeString(&KeyName,
-                      L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &KeyName,
-                            OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
-                            0,
-                            NULL);
-  Status = ZwCreateKey(&ResourceMapKey,
-                      KEY_ALL_ACCESS,
-                      &ObjectAttributes,
-                      0,
-                      NULL,
-                      REG_OPTION_VOLATILE,
-                      &Disposition);
-  if (!NT_SUCCESS(Status))
-      return Status;
-
-  RtlInitUnicodeString(&KeyName, Level1Key);
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &KeyName,
-                            OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
-                            ResourceMapKey,
-                            NULL);
-  Status = ZwCreateKey(&PnpMgrLevel1,
-                       KEY_ALL_ACCESS,
-                       &ObjectAttributes,
-                       0,
-                       NULL,
-                       REG_OPTION_VOLATILE,
-                       &Disposition);
-  ZwClose(ResourceMapKey);
-  if (!NT_SUCCESS(Status))
-      return Status;
-
-  RtlInitUnicodeString(&KeyName, Level2Key);
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &KeyName,
-                            OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
-                            PnpMgrLevel1,
-                            NULL);
-  Status = ZwCreateKey(&PnpMgrLevel2,
-                       KEY_ALL_ACCESS,
-                       &ObjectAttributes,
-                       0,
-                       NULL,
-                       REG_OPTION_VOLATILE,
-                       &Disposition);
-  ZwClose(PnpMgrLevel1);
-  if (!NT_SUCCESS(Status))
-      return Status;
-
-  if (DeviceNode->ResourceList)
-  {
-      WCHAR NameBuff[256];
-      UNICODE_STRING NameU;
-      UNICODE_STRING Suffix;
-      ULONG OldLength;
-
-      ASSERT(DeviceNode->ResourceListTranslated);
-
-      NameU.Buffer = NameBuff;
-      NameU.Length = 0;
-      NameU.MaximumLength = 256 * sizeof(WCHAR);
-
-      Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
-                                   DevicePropertyPhysicalDeviceObjectName,
-                                   NameU.MaximumLength,
-                                   NameU.Buffer,
-                                   &OldLength);
-      ASSERT(Status == STATUS_SUCCESS);
-
-      NameU.Length = (USHORT)OldLength;
-
-      RtlInitUnicodeString(&Suffix, L".Raw");
-      RtlAppendUnicodeStringToString(&NameU, &Suffix);
-
-      Status = ZwSetValueKey(PnpMgrLevel2,
-                             &NameU,
-                             0,
-                             REG_RESOURCE_LIST,
-                             DeviceNode->ResourceList,
-                             CM_RESOURCE_LIST_SIZE(DeviceNode->ResourceList));
-      if (!NT_SUCCESS(Status))
-      {
-          ZwClose(PnpMgrLevel2);
-          return Status;
-      }
-
-      /* "Remove" the suffix by setting the length back to what it used to be */
-      NameU.Length = (USHORT)OldLength;
-
-      RtlInitUnicodeString(&Suffix, L".Translated");
-      RtlAppendUnicodeStringToString(&NameU, &Suffix);
-
-      Status = ZwSetValueKey(PnpMgrLevel2,
-                             &NameU,
-                             0,
-                             REG_RESOURCE_LIST,
-                             DeviceNode->ResourceListTranslated,
-                             CM_RESOURCE_LIST_SIZE(DeviceNode->ResourceListTranslated));
-      ZwClose(PnpMgrLevel2);
-      if (!NT_SUCCESS(Status))
-          return Status;
-  }
-  else
-  {
-      ZwClose(PnpMgrLevel2);
-  }
-
-  IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED);
-
-  return STATUS_SUCCESS;
-}
-
-NTSTATUS
-IopUpdateResourceMapForPnPDevice(IN PDEVICE_NODE DeviceNode)
-{
-  return IopUpdateResourceMap(DeviceNode, L"PnP Manager", L"PnpManager");
-}
-
-NTSTATUS
-IopSetDeviceInstanceData(HANDLE InstanceKey,
-                         PDEVICE_NODE DeviceNode)
-{
-   OBJECT_ATTRIBUTES ObjectAttributes;
-   UNICODE_STRING KeyName;
-   HANDLE LogConfKey;
-   ULONG ResCount;
-   ULONG ListSize, ResultLength;
-   NTSTATUS Status;
-   HANDLE ControlHandle;
-
-   DPRINT("IopSetDeviceInstanceData() called\n");
-
-   /* Create the 'LogConf' key */
-   RtlInitUnicodeString(&KeyName, L"LogConf");
-   InitializeObjectAttributes(&ObjectAttributes,
-                              &KeyName,
-                              OBJ_CASE_INSENSITIVE,
-                              InstanceKey,
-                              NULL);
-   Status = ZwCreateKey(&LogConfKey,
-                        KEY_ALL_ACCESS,
-                        &ObjectAttributes,
-                        0,
-                        NULL,
-                        0,
-                        NULL);
-   if (NT_SUCCESS(Status))
-   {
-      /* Set 'BootConfig' value */
-      if (DeviceNode->BootResources != NULL)
-      {
-         ResCount = DeviceNode->BootResources->Count;
-         if (ResCount != 0)
-         {
-            ListSize = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
-
-            RtlInitUnicodeString(&KeyName, L"BootConfig");
-            Status = ZwSetValueKey(LogConfKey,
-                                   &KeyName,
-                                   0,
-                                   REG_RESOURCE_LIST,
-                                   DeviceNode->BootResources,
-                                   ListSize);
-         }
-      }
-
-      /* Set 'BasicConfigVector' value */
-      if (DeviceNode->ResourceRequirements != NULL &&
-         DeviceNode->ResourceRequirements->ListSize != 0)
-      {
-         RtlInitUnicodeString(&KeyName, L"BasicConfigVector");
-         Status = ZwSetValueKey(LogConfKey,
-                                &KeyName,
-                                0,
-                                REG_RESOURCE_REQUIREMENTS_LIST,
-                                DeviceNode->ResourceRequirements,
-                                DeviceNode->ResourceRequirements->ListSize);
-      }
-
-      ZwClose(LogConfKey);
-   }
-
-   /* Set the 'ConfigFlags' value */
-   RtlInitUnicodeString(&KeyName, L"ConfigFlags");
-   Status = ZwQueryValueKey(InstanceKey,
-                            &KeyName,
-                            KeyValueBasicInformation,
-                            NULL,
-                            0,
-                            &ResultLength);
-  if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
-  {
-    /* Write the default value */
-    ULONG DefaultConfigFlags = 0;
-    Status = ZwSetValueKey(InstanceKey,
-                           &KeyName,
-                           0,
-                           REG_DWORD,
-                           &DefaultConfigFlags,
-                           sizeof(DefaultConfigFlags));
-  }
-
-   /* Create the 'Control' key */
-   RtlInitUnicodeString(&KeyName, L"Control");
-   InitializeObjectAttributes(&ObjectAttributes,
-                              &KeyName,
-                              OBJ_CASE_INSENSITIVE,
-                              InstanceKey,
-                              NULL);
-   Status = ZwCreateKey(&ControlHandle, 0, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
-
-   if (NT_SUCCESS(Status))
-       ZwClose(ControlHandle);
-
-  DPRINT("IopSetDeviceInstanceData() done\n");
-
-  return Status;
-}
-
-BOOLEAN
-IopCheckForResourceConflict(
-   IN PCM_RESOURCE_LIST ResourceList1,
-   IN PCM_RESOURCE_LIST ResourceList2)
-{
-   ULONG i1, i2, ii1, ii2;
-   BOOLEAN Result = FALSE;
-
-   for (i1 = 0; i1 < ResourceList1->Count; i1++)
-   {
-      PCM_PARTIAL_RESOURCE_LIST ResList1 = &ResourceList1->List[i1].PartialResourceList;
-      for (i2 = 0; i2 < ResourceList2->Count; i2++)
-      {
-         PCM_PARTIAL_RESOURCE_LIST ResList2 = &ResourceList2->List[i2].PartialResourceList;
-         for (ii1 = 0; ii1 < ResList1->Count; ii1++)
-         {
-            PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc1 = &ResList1->PartialDescriptors[ii1];
-
-            if (ResDesc1->ShareDisposition == CmResourceShareShared)
-                continue;
-
-            for (ii2 = 0; ii2 < ResList2->Count; ii2++)
-            {
-               PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc2 = &ResList2->PartialDescriptors[ii2];
-
-               /* We don't care about shared resources */
-               if (ResDesc2->ShareDisposition == CmResourceShareShared)
-                   continue;
-
-               /* Make sure we're comparing the same types */
-               if (ResDesc1->Type != ResDesc2->Type)
-                   continue;
-
-               switch (ResDesc1->Type)
-               {
-                   case CmResourceTypeMemory:
-                      if ((ResDesc1->u.Memory.Start.QuadPart < ResDesc2->u.Memory.Start.QuadPart &&
-                           ResDesc1->u.Memory.Start.QuadPart + ResDesc1->u.Memory.Length >
-                           ResDesc2->u.Memory.Start.QuadPart) || (ResDesc2->u.Memory.Start.QuadPart <
-                           ResDesc1->u.Memory.Start.QuadPart && ResDesc2->u.Memory.Start.QuadPart +
-                           ResDesc2->u.Memory.Length > ResDesc1->u.Memory.Start.QuadPart))
-                      {
-                          DPRINT1("Resource conflict: Memory (0x%x to 0x%x vs. 0x%x to 0x%x)\n",
-                                  ResDesc1->u.Memory.Start.QuadPart, ResDesc1->u.Memory.Start.QuadPart +
-                                  ResDesc1->u.Memory.Length, ResDesc2->u.Memory.Start.QuadPart,
-                                  ResDesc2->u.Memory.Start.QuadPart + ResDesc2->u.Memory.Length);
-
-                          Result = TRUE;
-
-                          goto ByeBye;
-                      }
-                      break;
-
-                  case CmResourceTypePort:
-                      if ((ResDesc1->u.Port.Start.QuadPart < ResDesc2->u.Port.Start.QuadPart &&
-                           ResDesc1->u.Port.Start.QuadPart + ResDesc1->u.Port.Length >
-                           ResDesc2->u.Port.Start.QuadPart) || (ResDesc2->u.Port.Start.QuadPart <
-                           ResDesc1->u.Port.Start.QuadPart && ResDesc2->u.Port.Start.QuadPart +
-                           ResDesc2->u.Port.Length > ResDesc1->u.Port.Start.QuadPart))
-                      {
-                          DPRINT1("Resource conflict: Port (0x%x to 0x%x vs. 0x%x to 0x%x)\n",
-                                  ResDesc1->u.Port.Start.QuadPart, ResDesc1->u.Port.Start.QuadPart +
-                                  ResDesc1->u.Port.Length, ResDesc2->u.Port.Start.QuadPart,
-                                  ResDesc2->u.Port.Start.QuadPart + ResDesc2->u.Port.Length);
-
-                          Result = TRUE;
-
-                          goto ByeBye;
-                      }
-                      break;
-
-                  case CmResourceTypeInterrupt:
-                      if (ResDesc1->u.Interrupt.Vector == ResDesc2->u.Interrupt.Vector)
-                      {
-                         DPRINT1("Resource conflict: IRQ (0x%x 0x%x vs. 0x%x 0x%x)\n",
-                                 ResDesc1->u.Interrupt.Vector, ResDesc1->u.Interrupt.Level,
-                                 ResDesc2->u.Interrupt.Vector, ResDesc2->u.Interrupt.Level);
-
-                         Result = TRUE;
-
-                         goto ByeBye;
-                      }
-                      break;
-
-                  case CmResourceTypeBusNumber:
-                      if ((ResDesc1->u.BusNumber.Start < ResDesc2->u.BusNumber.Start &&
-                           ResDesc1->u.BusNumber.Start + ResDesc1->u.BusNumber.Length >
-                           ResDesc2->u.BusNumber.Start) || (ResDesc2->u.BusNumber.Start <
-                           ResDesc1->u.BusNumber.Start && ResDesc2->u.BusNumber.Start +
-                           ResDesc2->u.BusNumber.Length > ResDesc1->u.BusNumber.Start))
-                      {
-                         DPRINT1("Resource conflict: Bus number (0x%x to 0x%x vs. 0x%x to 0x%x)\n",
-                                  ResDesc1->u.BusNumber.Start, ResDesc1->u.BusNumber.Start +
-                                  ResDesc1->u.BusNumber.Length, ResDesc2->u.BusNumber.Start,
-                                  ResDesc2->u.BusNumber.Start + ResDesc2->u.BusNumber.Length);
-
-                         Result = TRUE;
-
-                         goto ByeBye;
-                      }
-                      break;
-
-                  case CmResourceTypeDma:
-                      if (ResDesc1->u.Dma.Channel == ResDesc2->u.Dma.Channel)
-                      {
-                         DPRINT1("Resource conflict: Dma (0x%x 0x%x vs. 0x%x 0x%x)\n",
-                                 ResDesc1->u.Dma.Channel, ResDesc1->u.Dma.Port,
-                                 ResDesc2->u.Dma.Channel, ResDesc2->u.Dma.Port);
-
-                         Result = TRUE;
-
-                         goto ByeBye;
-                      }
-                      break;
-               }
-            }
-         }
-      }
-   }
-
-ByeBye:
-
-#ifdef ENABLE_RESOURCE_CONFLICT_DETECTION
-   return Result;
-#else
-   return FALSE;
-#endif
-}
-
-NTSTATUS
-IopDetectResourceConflict(
-   IN PCM_RESOURCE_LIST ResourceList)
-{
-   OBJECT_ATTRIBUTES ObjectAttributes;
-   UNICODE_STRING KeyName;
-   HANDLE ResourceMapKey = INVALID_HANDLE_VALUE, ChildKey2 = INVALID_HANDLE_VALUE, ChildKey3 = INVALID_HANDLE_VALUE;
-   ULONG KeyInformationLength, RequiredLength, KeyValueInformationLength, KeyNameInformationLength;
-   PKEY_BASIC_INFORMATION KeyInformation;
-   PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
-   PKEY_VALUE_BASIC_INFORMATION KeyNameInformation;
-   ULONG ChildKeyIndex1 = 0, ChildKeyIndex2 = 0, ChildKeyIndex3 = 0;
-   NTSTATUS Status;
-
-   RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
-   InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, 0, NULL);
-   Status = ZwOpenKey(&ResourceMapKey, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes);
-   if (!NT_SUCCESS(Status))
-   {
-      /* The key is missing which means we are the first device */
-      return STATUS_SUCCESS;
-   }
-
-   while (TRUE)
-   {
-      Status = ZwEnumerateKey(ResourceMapKey,
-                              ChildKeyIndex1,
-                              KeyBasicInformation,
-                              NULL,
-                              0,
-                              &RequiredLength);
-      if (Status == STATUS_NO_MORE_ENTRIES)
-          break;
-      else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
-      {
-          KeyInformationLength = RequiredLength;
-          KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength);
-          if (!KeyInformation)
-          {
-              Status = STATUS_INSUFFICIENT_RESOURCES;
-              goto cleanup;
-          }
-
-          Status = ZwEnumerateKey(ResourceMapKey, 
-                                  ChildKeyIndex1,
-                                  KeyBasicInformation,
-                                  KeyInformation,
-                                  KeyInformationLength,
-                                  &RequiredLength);
-      }
-      else
-         goto cleanup;
-      ChildKeyIndex1++;
-      if (!NT_SUCCESS(Status))
-          goto cleanup;
-
-      KeyName.Buffer = KeyInformation->Name;
-      KeyName.MaximumLength = KeyName.Length = KeyInformation->NameLength;
-      InitializeObjectAttributes(&ObjectAttributes,
-                                 &KeyName,
-                                 OBJ_CASE_INSENSITIVE,
-                                 ResourceMapKey,
-                                 NULL);
-      Status = ZwOpenKey(&ChildKey2, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes);
-      ExFreePool(KeyInformation);
-      if (!NT_SUCCESS(Status))
-          goto cleanup;
-
-      while (TRUE)
-      {
-          Status = ZwEnumerateKey(ChildKey2, 
-                                  ChildKeyIndex2,
-                                  KeyBasicInformation,
-                                  NULL,
-                                  0,
-                                  &RequiredLength);
-          if (Status == STATUS_NO_MORE_ENTRIES)
-              break;
-          else if (Status == STATUS_BUFFER_TOO_SMALL)
-          {
-              KeyInformationLength = RequiredLength;
-              KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength);
-              if (!KeyInformation)
-              {
-                  Status = STATUS_INSUFFICIENT_RESOURCES;
-                  goto cleanup;
-              }
-
-              Status = ZwEnumerateKey(ChildKey2,
-                                      ChildKeyIndex2,
-                                      KeyBasicInformation,
-                                      KeyInformation,
-                                      KeyInformationLength,
-                                      &RequiredLength);
-          }
-          else
-              goto cleanup;
-          ChildKeyIndex2++;
-          if (!NT_SUCCESS(Status))
-              goto cleanup;
-
-          KeyName.Buffer = KeyInformation->Name;
-          KeyName.MaximumLength = KeyName.Length = KeyInformation->NameLength;
-          InitializeObjectAttributes(&ObjectAttributes,
-                                     &KeyName,
-                                     OBJ_CASE_INSENSITIVE,
-                                     ChildKey2,
-                                     NULL);
-          Status = ZwOpenKey(&ChildKey3, KEY_QUERY_VALUE, &ObjectAttributes);
-          ExFreePool(KeyInformation);
-          if (!NT_SUCCESS(Status))
-              goto cleanup;
-
-          while (TRUE)
-          {
-              Status = ZwEnumerateValueKey(ChildKey3,
-                                           ChildKeyIndex3,
-                                           KeyValuePartialInformation,
-                                           NULL,
-                                           0,
-                                           &RequiredLength);
-              if (Status == STATUS_NO_MORE_ENTRIES)
-                  break;
-              else if (Status == STATUS_BUFFER_TOO_SMALL)
-              {
-                  KeyValueInformationLength = RequiredLength;
-                  KeyValueInformation = ExAllocatePool(PagedPool, KeyValueInformationLength);
-                  if (!KeyValueInformation)
-                  {
-                      Status = STATUS_INSUFFICIENT_RESOURCES;
-                      goto cleanup;
-                  }
-
-                  Status = ZwEnumerateValueKey(ChildKey3,
-                                               ChildKeyIndex3,
-                                               KeyValuePartialInformation,
-                                               KeyValueInformation,
-                                               KeyValueInformationLength,
-                                               &RequiredLength);
-              }
-              else
-                  goto cleanup;
-              if (!NT_SUCCESS(Status))
-                  goto cleanup;
-
-              Status = ZwEnumerateValueKey(ChildKey3,
-                                           ChildKeyIndex3,
-                                           KeyValueBasicInformation,
-                                           NULL,
-                                           0,
-                                           &RequiredLength);
-              if (Status == STATUS_BUFFER_TOO_SMALL)
-              {
-                  KeyNameInformationLength = RequiredLength;
-                  KeyNameInformation = ExAllocatePool(PagedPool, KeyNameInformationLength + sizeof(WCHAR));
-                  if (!KeyNameInformation)
-                  {
-                      Status = STATUS_INSUFFICIENT_RESOURCES;
-                      goto cleanup;
-                  }
-
-                  Status = ZwEnumerateValueKey(ChildKey3,
-                                               ChildKeyIndex3,
-                                               KeyValueBasicInformation,
-                                               KeyNameInformation,
-                                               KeyNameInformationLength,
-                                               &RequiredLength);
-              }
-              else
-                  goto cleanup;
-
-              ChildKeyIndex3++;
-
-              if (!NT_SUCCESS(Status))
-                  goto cleanup;
-
-              KeyNameInformation->Name[KeyNameInformation->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
-
-              /* Skip translated entries */
-              if (wcsstr(KeyNameInformation->Name, L".Translated"))
-              {
-                  ExFreePool(KeyNameInformation);
-                  continue;
-              }
-
-              ExFreePool(KeyNameInformation);
-
-              if (IopCheckForResourceConflict(ResourceList,
-                                              (PCM_RESOURCE_LIST)KeyValueInformation->Data))
-              {
-                  ExFreePool(KeyValueInformation);
-                  Status = STATUS_CONFLICTING_ADDRESSES;
-                  goto cleanup;
-              }
-
-              ExFreePool(KeyValueInformation);
-          }
-      }
-   }
-
-cleanup:
-   if (ResourceMapKey != INVALID_HANDLE_VALUE)
-       ZwClose(ResourceMapKey);
-   if (ChildKey2 != INVALID_HANDLE_VALUE)
-       ZwClose(ChildKey2);
-   if (ChildKey3 != INVALID_HANDLE_VALUE)
-       ZwClose(ChildKey3);
-
-   if (Status == STATUS_NO_MORE_ENTRIES)
-       Status = STATUS_SUCCESS;
-
-   return Status;
-}
-                
-NTSTATUS
-IopAssignDeviceResources(
-   IN PDEVICE_NODE DeviceNode,
-   OUT ULONG *pRequiredSize)
-{
-   PIO_RESOURCE_LIST ResourceList;
-   PIO_RESOURCE_DESCRIPTOR ResourceDescriptor;
-   PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw;
-   PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
-   ULONG NumberOfResources = 0;
-   ULONG Size;
-   ULONG i, j;
-   NTSTATUS Status;
-
-   if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements)
-   {
-      /* No resource needed for this device */
-      DeviceNode->ResourceList = NULL;
-      *pRequiredSize = 0;
-      return STATUS_SUCCESS;
-   }
-
-   /* Fill DeviceNode->ResourceList
-    * FIXME: the PnP arbiter should go there!
-    * Actually, use the BootResources if provided, else the resource list #0
-    */
-
-   if (DeviceNode->BootResources)
-   {
-      /* Browse the boot resources to know if we have some custom structures */
-      Size = FIELD_OFFSET(CM_RESOURCE_LIST, List);
-      for (i = 0; i < DeviceNode->BootResources->Count; i++)
-      {
-         pPartialResourceList = &DeviceNode->BootResources->List[i].PartialResourceList;
-         Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors)
-            + pPartialResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
-         for (j = 0; j < pPartialResourceList->Count; j++)
-         {
-            if (pPartialResourceList->PartialDescriptors[j].Type == CmResourceTypeDeviceSpecific)
-               Size += pPartialResourceList->PartialDescriptors[j].u.DeviceSpecificData.DataSize;
-         }
-      }
-
-      DeviceNode->ResourceList = ExAllocatePool(PagedPool, Size);
-      if (!DeviceNode->ResourceList)
-      {
-         Status = STATUS_NO_MEMORY;
-         goto ByeBye;
-      }
-      RtlCopyMemory(DeviceNode->ResourceList, DeviceNode->BootResources, Size);
-
-      Status = IopDetectResourceConflict(DeviceNode->ResourceList);
-      if (!NT_SUCCESS(Status))
-          goto ByeBye;
-
-      *pRequiredSize = Size;
-      return STATUS_SUCCESS;
-   }
-
-   /* Ok, here, we have to use the device requirement list */
-   ResourceList = &DeviceNode->ResourceRequirements->List[0];
-   if (ResourceList->Version != 1 || ResourceList->Revision != 1)
-   {
-      Status = STATUS_REVISION_MISMATCH;
-      goto ByeBye;
-   }
-
-   Size = sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
-   DeviceNode->ResourceList = ExAllocatePool(PagedPool, Size);
-   if (!DeviceNode->ResourceList)
-   {
-      Status = STATUS_NO_MEMORY;
-      goto ByeBye;
-   }
-
-   DeviceNode->ResourceList->Count = 1;
-   DeviceNode->ResourceList->List[0].InterfaceType = DeviceNode->ResourceRequirements->InterfaceType;
-   DeviceNode->ResourceList->List[0].BusNumber = DeviceNode->ResourceRequirements->BusNumber;
-   DeviceNode->ResourceList->List[0].PartialResourceList.Version = 1;
-   DeviceNode->ResourceList->List[0].PartialResourceList.Revision = 1;
-
-   for (i = 0; i < ResourceList->Count; i++)
-   {
-      ResourceDescriptor = &ResourceList->Descriptors[i];
-
-      if (ResourceDescriptor->Option == 0 || ResourceDescriptor->Option == IO_RESOURCE_PREFERRED)
-      {
-         DescriptorRaw = &DeviceNode->ResourceList->List[0].PartialResourceList.PartialDescriptors[NumberOfResources];
-         NumberOfResources++;
-
-         /* Copy ResourceDescriptor to DescriptorRaw and DescriptorTranslated */
-         DescriptorRaw->Type = ResourceDescriptor->Type;
-         DescriptorRaw->ShareDisposition = ResourceDescriptor->ShareDisposition;
-         DescriptorRaw->Flags = ResourceDescriptor->Flags;
-         switch (ResourceDescriptor->Type)
-         {
-            case CmResourceTypePort:
-            {
-               DescriptorRaw->u.Port.Start = ResourceDescriptor->u.Port.MinimumAddress;
-               DescriptorRaw->u.Port.Length = ResourceDescriptor->u.Port.Length;
-               break;
-            }
-            case CmResourceTypeInterrupt:
-            {
-               INTERFACE_TYPE BusType;
-               ULONG SlotNumber;
-               ULONG ret;
-               UCHAR Irq;
-
-               DescriptorRaw->u.Interrupt.Level = 0;
-               DescriptorRaw->u.Interrupt.Vector = ResourceDescriptor->u.Interrupt.MinimumVector;
-               /* FIXME: HACK: if we have a PCI device, we try
-                * to keep the IRQ assigned by the BIOS */
-               if (NT_SUCCESS(IoGetDeviceProperty(
-                  DeviceNode->PhysicalDeviceObject,
-                  DevicePropertyLegacyBusType,
-                  sizeof(INTERFACE_TYPE),
-                  &BusType,
-                  &ret)) && BusType == PCIBus)
-               {
-                  /* We have a PCI bus */
-                  if (NT_SUCCESS(IoGetDeviceProperty(
-                     DeviceNode->PhysicalDeviceObject,
-                     DevicePropertyAddress,
-                     sizeof(ULONG),
-                     &SlotNumber,
-                     &ret)) && SlotNumber > 0)
-                  {
-                     /* We have a good slot number */
-                     ret = HalGetBusDataByOffset(PCIConfiguration,
-                                                 DeviceNode->ResourceRequirements->BusNumber,
-                                                 SlotNumber,
-                                                 &Irq,
-                                                 0x3c /* PCI_INTERRUPT_LINE */,
-                                                 sizeof(UCHAR));
-                     if (ret != 0 && ret != 2
-                         && ResourceDescriptor->u.Interrupt.MinimumVector <= Irq
-                         && ResourceDescriptor->u.Interrupt.MaximumVector >= Irq)
-                     {
-                        /* The device already has an assigned IRQ */
-                        DescriptorRaw->u.Interrupt.Vector = Irq;
-                     }
-                     else
-                     {
-                         DPRINT1("Trying to assign IRQ 0x%lx to %wZ\n",
-                            DescriptorRaw->u.Interrupt.Vector,
-                            &DeviceNode->InstancePath);
-                         Irq = (UCHAR)DescriptorRaw->u.Interrupt.Vector;
-                         ret = HalSetBusDataByOffset(PCIConfiguration,
-                            DeviceNode->ResourceRequirements->BusNumber,
-                            SlotNumber,
-                            &Irq,
-                            0x3c /* PCI_INTERRUPT_LINE */,
-                            sizeof(UCHAR));
-                         if (ret == 0 || ret == 2)
-                            ASSERT(FALSE);
-                     }
-                  }
-               }
-               break;
-            }
-            case CmResourceTypeMemory:
-            {
-               DescriptorRaw->u.Memory.Start = ResourceDescriptor->u.Memory.MinimumAddress;
-               DescriptorRaw->u.Memory.Length = ResourceDescriptor->u.Memory.Length;
-               break;
-            }
-            case CmResourceTypeDma:
-            {
-               DescriptorRaw->u.Dma.Channel = ResourceDescriptor->u.Dma.MinimumChannel;
-               DescriptorRaw->u.Dma.Port = 0; /* FIXME */
-               DescriptorRaw->u.Dma.Reserved1 = 0;
-               break;
-            }
-            case CmResourceTypeBusNumber:
-            {
-               DescriptorRaw->u.BusNumber.Start = ResourceDescriptor->u.BusNumber.MinBusNumber;
-               DescriptorRaw->u.BusNumber.Length = ResourceDescriptor->u.BusNumber.Length;
-               DescriptorRaw->u.BusNumber.Reserved = ResourceDescriptor->u.BusNumber.Reserved;
-               break;
-            }
-            /*CmResourceTypeDevicePrivate:
-            case CmResourceTypePcCardConfig:
-            case CmResourceTypeMfCardConfig:
-            {
-               RtlCopyMemory(
-                  &DescriptorRaw->u.DevicePrivate,
-                  &ResourceDescriptor->u.DevicePrivate,
-                  sizeof(ResourceDescriptor->u.DevicePrivate));
-               RtlCopyMemory(
-                  &DescriptorTranslated->u.DevicePrivate,
-                  &ResourceDescriptor->u.DevicePrivate,
-                  sizeof(ResourceDescriptor->u.DevicePrivate));
-               break;
-            }*/
-            default:
-               DPRINT1("IopAssignDeviceResources(): unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type);
-               NumberOfResources--;
-         }
-      }
-
-   }
-
-   DeviceNode->ResourceList->List[0].PartialResourceList.Count = NumberOfResources;
-
-   Status = IopDetectResourceConflict(DeviceNode->ResourceList);
-   if (!NT_SUCCESS(Status))
-       goto ByeBye;
+            return STATUS_SUCCESS;
+        }
 
-   *pRequiredSize = Size;
-   return STATUS_SUCCESS;
+        /* Start with this new parent key */
+        hParent = hKey;
+        Current++;
+        KeyName.Buffer = (LPWSTR)Current;
+    }
 
-ByeBye:
-   if (DeviceNode->ResourceList)
-   {
-      ExFreePool(DeviceNode->ResourceList);
-      DeviceNode->ResourceList = NULL;
-   }
-   *pRequiredSize = 0;
-   return Status;
+    return STATUS_UNSUCCESSFUL;
 }
 
-
 NTSTATUS
-IopTranslateDeviceResources(
-   IN PDEVICE_NODE DeviceNode,
-   IN ULONG RequiredSize)
+IopSetDeviceInstanceData(HANDLE InstanceKey,
+                         PDEVICE_NODE DeviceNode)
 {
-   PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
-   PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated;
-   ULONG i, j;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   UNICODE_STRING KeyName;
+   HANDLE LogConfKey;
+   ULONG ResCount;
+   ULONG ResultLength;
    NTSTATUS Status;
+   HANDLE ControlHandle;
 
-   if (!DeviceNode->ResourceList)
-   {
-      DeviceNode->ResourceListTranslated = NULL;
-      return STATUS_SUCCESS;
-   }
-
-   /* That's easy to translate a resource list. Just copy the
-    * untranslated one and change few fields in the copy
-    */
-   DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, RequiredSize);
-   if (!DeviceNode->ResourceListTranslated)
-   {
-      Status =STATUS_NO_MEMORY;
-      goto cleanup;
-   }
-   RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, RequiredSize);
+   DPRINT("IopSetDeviceInstanceData() called\n");
 
-   for (i = 0; i < DeviceNode->ResourceList->Count; i++)
+   /* Create the 'LogConf' key */
+   RtlInitUnicodeString(&KeyName, L"LogConf");
+   InitializeObjectAttributes(&ObjectAttributes,
+                              &KeyName,
+                              OBJ_CASE_INSENSITIVE,
+                              InstanceKey,
+                              NULL);
+   Status = ZwCreateKey(&LogConfKey,
+                        KEY_ALL_ACCESS,
+                        &ObjectAttributes,
+                        0,
+                        NULL,
+                        0,
+                        NULL);
+   if (NT_SUCCESS(Status))
    {
-      pPartialResourceList = &DeviceNode->ResourceList->List[i].PartialResourceList;
-      for (j = 0; j < pPartialResourceList->Count; j++)
+      /* Set 'BootConfig' value */
+      if (DeviceNode->BootResources != NULL)
       {
-         DescriptorRaw = &pPartialResourceList->PartialDescriptors[j];
-         DescriptorTranslated = &DeviceNode->ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j];
-         switch (DescriptorRaw->Type)
+         ResCount = DeviceNode->BootResources->Count;
+         if (ResCount != 0)
          {
-            case CmResourceTypePort:
-            {
-               ULONG AddressSpace = 1; /* IO space */
-               if (!HalTranslateBusAddress(
-                  DeviceNode->ResourceList->List[i].InterfaceType,
-                  DeviceNode->ResourceList->List[i].BusNumber,
-                  DescriptorRaw->u.Port.Start,
-                  &AddressSpace,
-                  &DescriptorTranslated->u.Port.Start))
-               {
-                  Status = STATUS_UNSUCCESSFUL;
-                  goto cleanup;
-               }
-               break;
-            }
-            case CmResourceTypeInterrupt:
-            {
-               DescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector(
-                  DeviceNode->ResourceList->List[i].InterfaceType,
-                  DeviceNode->ResourceList->List[i].BusNumber,
-                  DescriptorRaw->u.Interrupt.Level,
-                  DescriptorRaw->u.Interrupt.Vector,
-                  (PKIRQL)&DescriptorTranslated->u.Interrupt.Level,
-                  &DescriptorRaw->u.Interrupt.Affinity);
-               break;
-            }
-            case CmResourceTypeMemory:
-            {
-               ULONG AddressSpace = 0; /* Memory space */
-               if (!HalTranslateBusAddress(
-                  DeviceNode->ResourceList->List[i].InterfaceType,
-                  DeviceNode->ResourceList->List[i].BusNumber,
-                  DescriptorRaw->u.Memory.Start,
-                  &AddressSpace,
-                  &DescriptorTranslated->u.Memory.Start))
-               {
-                  Status = STATUS_UNSUCCESSFUL;
-                  goto cleanup;
-               }
-            }
-
-            case CmResourceTypeDma:
-            case CmResourceTypeBusNumber:
-            case CmResourceTypeDeviceSpecific:
-               /* Nothing to do */
-               break;
-            default:
-               DPRINT1("Unknown resource descriptor type 0x%x\n", DescriptorRaw->Type);
-               Status = STATUS_NOT_IMPLEMENTED;
-               goto cleanup;
+            RtlInitUnicodeString(&KeyName, L"BootConfig");
+            Status = ZwSetValueKey(LogConfKey,
+                                   &KeyName,
+                                   0,
+                                   REG_RESOURCE_LIST,
+                                   DeviceNode->BootResources,
+                                   IopCalculateResourceListSize(DeviceNode->BootResources));
          }
       }
-   }
-   return STATUS_SUCCESS;
 
-cleanup:
-   /* Yes! Also delete ResourceList because ResourceList and
-    * ResourceListTranslated should be a pair! */
-   ExFreePool(DeviceNode->ResourceList);
-   DeviceNode->ResourceList = NULL;
-   if (DeviceNode->ResourceListTranslated)
-   {
-      ExFreePool(DeviceNode->ResourceListTranslated);
-      DeviceNode->ResourceList = NULL;
+      /* Set 'BasicConfigVector' value */
+      if (DeviceNode->ResourceRequirements != NULL &&
+         DeviceNode->ResourceRequirements->ListSize != 0)
+      {
+         RtlInitUnicodeString(&KeyName, L"BasicConfigVector");
+         Status = ZwSetValueKey(LogConfKey,
+                                &KeyName,
+                                0,
+                                REG_RESOURCE_REQUIREMENTS_LIST,
+                                DeviceNode->ResourceRequirements,
+                                DeviceNode->ResourceRequirements->ListSize);
+      }
+
+      ZwClose(LogConfKey);
    }
-   return Status;
-}
 
+   /* Set the 'ConfigFlags' value */
+   RtlInitUnicodeString(&KeyName, L"ConfigFlags");
+   Status = ZwQueryValueKey(InstanceKey,
+                            &KeyName,
+                            KeyValueBasicInformation,
+                            NULL,
+                            0,
+                            &ResultLength);
+  if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+  {
+    /* Write the default value */
+    ULONG DefaultConfigFlags = 0;
+    Status = ZwSetValueKey(InstanceKey,
+                           &KeyName,
+                           0,
+                           REG_DWORD,
+                           &DefaultConfigFlags,
+                           sizeof(DefaultConfigFlags));
+  }
+
+   /* Create the 'Control' key */
+   RtlInitUnicodeString(&KeyName, L"Control");
+   InitializeObjectAttributes(&ObjectAttributes,
+                              &KeyName,
+                              OBJ_CASE_INSENSITIVE,
+                              InstanceKey,
+                              NULL);
+   Status = ZwCreateKey(&ControlHandle, 0, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
+
+   if (NT_SUCCESS(Status))
+       ZwClose(ControlHandle);
+
+  DPRINT("IopSetDeviceInstanceData() done\n");
+
+  return Status;
+}
 
 /*
  * IopGetParentIdPrefix
@@ -1959,7 +1289,7 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
    /*
     * Create registry key for the instance id, if it doesn't exist yet
     */
-   Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, &InstanceKey);
+   Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey);
    if (!NT_SUCCESS(Status))
    {
       DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
@@ -2189,7 +1519,7 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
    {
       DeviceNode->BootResources =
          (PCM_RESOURCE_LIST)IoStatusBlock.Information;
-      DeviceNode->Flags |= DNF_HAS_BOOT_CONFIG;
+      IopDeviceNodeSetFlag(DeviceNode, DNF_HAS_BOOT_CONFIG);
    }
    else
    {
@@ -2208,10 +1538,6 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
    {
       DeviceNode->ResourceRequirements =
          (PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information;
-      if (IoStatusBlock.Information)
-         IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_REPORTED);
-      else
-         IopDeviceNodeSetFlag(DeviceNode, DNF_NO_RESOURCE_REQUIRED);
    }
    else
    {
@@ -2219,7 +1545,6 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
       DeviceNode->ResourceRequirements = NULL;
    }
 
-
    if (InstanceKey != NULL)
    {
       IopSetDeviceInstanceData(InstanceKey, DeviceNode);
@@ -2483,14 +1808,8 @@ IopActionConfigureChildServices(PDEVICE_NODE DeviceNode,
             DPRINT1("%wZ is using parent bus driver (%wZ)\n", &DeviceNode->InstancePath, &ParentDeviceNode->ServiceName);
 
             DeviceNode->ServiceName.Length = 0;
-            DeviceNode->ServiceName.MaximumLength = ParentDeviceNode->ServiceName.MaximumLength;
-            DeviceNode->ServiceName.Buffer = ExAllocatePool(PagedPool, DeviceNode->ServiceName.MaximumLength);
-            if (!DeviceNode->ServiceName.Buffer)
-                return STATUS_SUCCESS;
-
-            RtlCopyUnicodeString(&DeviceNode->ServiceName, &ParentDeviceNode->ServiceName);
-
-            IopDeviceNodeSetFlag(DeviceNode, DNF_LEGACY_DRIVER);
+            DeviceNode->ServiceName.MaximumLength = 0;
+            DeviceNode->ServiceName.Buffer = NULL;
          }
          else if (ClassGUID.Length != 0)
          {
@@ -2569,10 +1888,23 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
       return STATUS_UNSUCCESSFUL;
    }
 #endif
+   if (IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED) ||
+       IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) ||
+       IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED))
+       return STATUS_SUCCESS;
 
-   if (!IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED) &&
-       !IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) &&
-       !IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED))
+   if (DeviceNode->ServiceName.Buffer == NULL)
+   {
+      /* We don't need to worry about loading the driver because we're
+       * being driven in raw mode so our parent must be loaded to get here */
+      Status = IopStartDevice(DeviceNode);
+      if (!NT_SUCCESS(Status))
+      {
+          DPRINT1("IopStartDevice(%wZ) failed with status 0x%08x\n",
+                  &DeviceNode->InstancePath, Status);
+      }
+   }
+   else
    {
       PLDR_DATA_TABLE_ENTRY ModuleObject;
       PDRIVER_OBJECT DriverObject;
@@ -2615,24 +1947,8 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
       /* Driver is loaded and initialized at this point */
       if (NT_SUCCESS(Status))
       {
-         /* Attach lower level filter drivers. */
-         IopAttachFilterDrivers(DeviceNode, TRUE);
-         /* Initialize the function driver for the device node */
-         Status = IopInitializeDevice(DeviceNode, DriverObject);
-
-         if (NT_SUCCESS(Status))
-         {
-            /* Attach upper level filter drivers. */
-            IopAttachFilterDrivers(DeviceNode, FALSE);
-            IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
-
-            Status = IopStartDevice(DeviceNode);
-         }
-         else
-         {
-            DPRINT1("IopInitializeDevice(%wZ) failed with status 0x%08x\n",
-                    &DeviceNode->InstancePath, Status);
-         }
+          /* Initialize the device, including all filters */
+          Status = PipCallDriverAddDevice(DeviceNode, FALSE, DriverObject);
       }
       else
       {
@@ -2649,11 +1965,6 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
          }
       }
    }
-   else
-   {
-      DPRINT("Device %wZ is disabled or already initialized\n",
-         &DeviceNode->InstancePath);
-   }
 
    return STATUS_SUCCESS;
 }
@@ -2696,7 +2007,6 @@ IopEnumerateDetectedDevices(
    IN ULONG ParentBootResourcesLength)
 {
    UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
-   UNICODE_STRING DeviceDescU = RTL_CONSTANT_STRING(L"DeviceDesc");
    UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
    UNICODE_STRING ConfigurationDataU = RTL_CONSTANT_STRING(L"Configuration Data");
    UNICODE_STRING BootConfigU = RTL_CONSTANT_STRING(L"BootConfig");
@@ -2743,7 +2053,8 @@ IopEnumerateDetectedDevices(
    UNICODE_STRING HardwareIdKey;
    PUNICODE_STRING pHardwareId;
    ULONG DeviceIndex = 0;
-   BOOLEAN IsDeviceDesc;
+   PUCHAR CmResourceList;
+   ULONG ListCount;
 
     if (RelativePath)
     {
@@ -2850,7 +2161,7 @@ IopEnumerateDetectedDevices(
             BootResourcesLength = pValueInformation->DataLength;
          else
             BootResourcesLength = ParentBootResourcesLength
-               + pValueInformation->DataLength
+            + pValueInformation->DataLength
                - Header;
          BootResources = ExAllocatePool(PagedPool, BootResourcesLength);
          if (!BootResources)
@@ -2858,7 +2169,7 @@ IopEnumerateDetectedDevices(
             DPRINT("ExAllocatePool() failed\n");
             goto nextdevice;
          }
-         if (ParentBootResourcesLength == 0)
+         if (ParentBootResourcesLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
          {
             RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
          }
@@ -2970,31 +2281,26 @@ IopEnumerateDetectedDevices(
       {
          pHardwareId = &HardwareIdSerial;
          DeviceIndex = DeviceIndexSerial++;
-         IsDeviceDesc = TRUE;
       }
       else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierKeyboard, FALSE) == 0)
       {
          pHardwareId = &HardwareIdKeyboard;
          DeviceIndex = DeviceIndexKeyboard++;
-         IsDeviceDesc = FALSE;
       }
       else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierMouse, FALSE) == 0)
       {
          pHardwareId = &HardwareIdMouse;
          DeviceIndex = DeviceIndexMouse++;
-         IsDeviceDesc = FALSE;
       }
       else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierParallel, FALSE) == 0)
       {
          pHardwareId = &HardwareIdParallel;
          DeviceIndex = DeviceIndexParallel++;
-         IsDeviceDesc = FALSE;
       }
       else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierFloppy, FALSE) == 0)
       {
          pHardwareId = &HardwareIdFloppy;
          DeviceIndex = DeviceIndexFloppy++;
-         IsDeviceDesc = FALSE;
       }
       else if (NT_SUCCESS(Status))
       {
@@ -3003,13 +2309,11 @@ IopEnumerateDetectedDevices(
          {
             pHardwareId = &HardwareIdPci;
             DeviceIndex = DeviceIndexPci++;
-            IsDeviceDesc = FALSE;
          }
          else if (RtlCompareUnicodeString(&ValueName, &IdentifierIsa, FALSE) == 0)
          {
             pHardwareId = &HardwareIdIsa;
             DeviceIndex = DeviceIndexIsa++;
-            IsDeviceDesc = FALSE;
          }
          else
          {
@@ -3061,16 +2365,6 @@ IopEnumerateDetectedDevices(
          goto nextdevice;
       }
       DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, &HardwareIdKey);
-      if (IsDeviceDesc)
-      {
-         Status = ZwSetValueKey(hLevel2Key, &DeviceDescU, 0, REG_SZ, ValueName.Buffer, ValueName.MaximumLength);
-         if (!NT_SUCCESS(Status))
-         {
-            DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
-            ZwDeleteKey(hLevel2Key);
-            goto nextdevice;
-         }
-      }
       Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength);
       if (!NT_SUCCESS(Status))
       {
@@ -3094,10 +2388,29 @@ IopEnumerateDetectedDevices(
          ZwDeleteKey(hLevel2Key);
          goto nextdevice;
       }
-      if (BootResourcesLength > 0)
+      if (BootResourcesLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
       {
+         CmResourceList = ExAllocatePool(PagedPool, BootResourcesLength + sizeof(ULONG));
+         if (!CmResourceList)
+         {
+            ZwClose(hLogConf);
+            ZwDeleteKey(hLevel2Key);
+            goto nextdevice;
+         }
+
+         /* Add the list count (1st member of CM_RESOURCE_LIST) */
+         ListCount = 1;
+         RtlCopyMemory(CmResourceList,
+                       &ListCount,
+                       sizeof(ULONG));
+
+         /* Now add the actual list (2nd member of CM_RESOURCE_LIST) */
+         RtlCopyMemory(CmResourceList + sizeof(ULONG),
+                       BootResources,
+                       BootResourcesLength);
+
          /* Save boot resources to 'LogConf\BootConfig' */
-         Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_FULL_RESOURCE_DESCRIPTOR, BootResources, BootResourcesLength);
+         Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_RESOURCE_LIST, CmResourceList, BootResourcesLength + sizeof(ULONG));
          if (!NT_SUCCESS(Status))
          {
             DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
@@ -3110,7 +2423,10 @@ IopEnumerateDetectedDevices(
 
 nextdevice:
       if (BootResources && BootResources != ParentBootResources)
+      {
          ExFreePool(BootResources);
+         BootResources = NULL;
+      }
       if (hLevel2Key)
       {
          ZwClose(hLevel2Key);
@@ -3277,7 +2593,8 @@ cleanup:
 #endif
 }
 
-static NTSTATUS INIT_FUNCTION
+NTSTATUS
+NTAPI
 IopUpdateRootKey(VOID)
 {
    UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum");
@@ -3384,6 +2701,131 @@ IopOpenRegistryKeyEx(PHANDLE KeyHandle,
     return Status;
 }
 
+NTSTATUS
+NTAPI
+IopCreateRegistryKeyEx(OUT PHANDLE Handle,
+                       IN HANDLE RootHandle OPTIONAL,
+                       IN PUNICODE_STRING KeyName,
+                       IN ACCESS_MASK DesiredAccess,
+                       IN ULONG CreateOptions,
+                       OUT PULONG Disposition OPTIONAL)
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    ULONG KeyDisposition, RootHandleIndex = 0, i = 1, NestedCloseLevel = 0, Length;
+    HANDLE HandleArray[2];
+    BOOLEAN Recursing = TRUE;
+    PWCHAR pp, p, p1;
+    UNICODE_STRING KeyString;
+    NTSTATUS Status = STATUS_SUCCESS;
+    PAGED_CODE();
+    
+    /* P1 is start, pp is end */
+    p1 = KeyName->Buffer;
+    pp = (PVOID)((ULONG_PTR)p1 + KeyName->Length);
+    
+    /* Create the target key */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               KeyName,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               RootHandle,
+                               NULL);
+    Status = ZwCreateKey(&HandleArray[i],
+                         DesiredAccess,
+                         &ObjectAttributes,
+                         0,
+                         NULL,
+                         CreateOptions,
+                         &KeyDisposition);
+
+    /* Now we check if this failed */
+    if ((Status == STATUS_OBJECT_NAME_NOT_FOUND) && (RootHandle))
+    {
+        /* Target key failed, so we'll need to create its parent. Setup array */
+        HandleArray[0] = NULL;
+        HandleArray[1] = RootHandle;
+        
+        /* Keep recursing for each missing parent */
+        while (Recursing)
+        {
+            /* And if we're deep enough, close the last handle */
+            if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
+            /* We're setup to ping-pong between the two handle array entries */
+            RootHandleIndex = i;
+            i = (i + 1) & 1;
+            
+            /* Clear the one we're attempting to open now */
+            HandleArray[i] = NULL;
+            
+            /* Process the parent key name */
+            for (p = p1; ((p < pp) && (*p != OBJ_NAME_PATH_SEPARATOR)); p++);
+            Length = (p - p1) * sizeof(WCHAR);
+            
+            /* Is there a parent name? */
+            if (Length)
+            {
+                /* Build the unicode string for it */
+                KeyString.Buffer = p1;
+                KeyString.Length = KeyString.MaximumLength = Length;
+                
+                /* Now try opening the parent */
+                InitializeObjectAttributes(&ObjectAttributes,
+                                           &KeyString,
+                                           OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                                           HandleArray[RootHandleIndex],
+                                           NULL);
+                Status = ZwCreateKey(&HandleArray[i],
+                                     DesiredAccess,
+                                     &ObjectAttributes,
+                                     0,
+                                     NULL,
+                                     CreateOptions,
+                                     &KeyDisposition);
+                if (NT_SUCCESS(Status))
+                {
+                    /* It worked, we have one more handle */
+                    NestedCloseLevel++;
+                }
+                else
+                {
+                    /* Parent key creation failed, abandon loop */
+                    Recursing = FALSE;
+                    continue;
+                }
+            }
+            else
+            {
+                /* We don't have a parent name, probably corrupted key name */
+                Status = STATUS_INVALID_PARAMETER;
+                Recursing = FALSE;
+                continue;
+            }
+            
+            /* Now see if there's more parents to create */
+            p1 = p + 1;
+            if ((p == pp) || (p1 == pp))
+            {
+                /* We're done, hopefully successfully, so stop */
+                Recursing = FALSE;
+            }
+        }
+        
+        /* Outer loop check for handle nesting that requires closing the top handle */
+        if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
+    }
+    
+    /* Check if we broke out of the loop due to success */
+    if (NT_SUCCESS(Status))
+    {
+        /* Return the target handle (we closed all the parent ones) and disposition */
+        *Handle = HandleArray[i];
+        if (Disposition) *Disposition = KeyDisposition;
+    }
+    
+    /* Return the success state */
+    return Status;
+}
+
 NTSTATUS
 NTAPI
 IopGetRegistryValue(IN HANDLE Handle,
@@ -3429,95 +2871,6 @@ IopGetRegistryValue(IN HANDLE Handle,
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS INIT_FUNCTION
-NTAPI
-PnpDriverInitializeEmpty(IN struct _DRIVER_OBJECT *DriverObject, IN PUNICODE_STRING RegistryPath)
-{
-   return STATUS_SUCCESS;
-}
-
-VOID INIT_FUNCTION
-PnpInit(VOID)
-{
-    PDEVICE_OBJECT Pdo;
-    NTSTATUS Status;
-
-    DPRINT("PnpInit()\n");
-
-    KeInitializeSpinLock(&IopDeviceTreeLock);
-       ExInitializeFastMutex(&IopBusTypeGuidListLock);
-       
-    /* Initialize the Bus Type GUID List */
-    IopBusTypeGuidList = ExAllocatePool(NonPagedPool, sizeof(IO_BUS_TYPE_GUID_LIST));
-    if (!IopBusTypeGuidList) {
-       DPRINT1("ExAllocatePool() failed\n");
-       KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 0, 0, 0);
-    }
-
-    RtlZeroMemory(IopBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST));
-    ExInitializeFastMutex(&IopBusTypeGuidList->Lock);
-
-    /* Initialize PnP-Event notification support */
-    Status = IopInitPlugPlayEvents();
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("IopInitPlugPlayEvents() failed\n");
-        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
-    }
-
-    /*
-    * Create root device node
-    */
-
-    Status = IopCreateDriver(NULL, PnpDriverInitializeEmpty, NULL, 0, 0, &IopRootDriverObject);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("IoCreateDriverObject() failed\n");
-        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
-    }
-
-    Status = IoCreateDevice(IopRootDriverObject, 0, NULL, FILE_DEVICE_CONTROLLER,
-        0, FALSE, &Pdo);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("IoCreateDevice() failed\n");
-        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
-    }
-
-    Status = IopCreateDeviceNode(NULL, Pdo, NULL, &IopRootDeviceNode);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Insufficient resources\n");
-        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
-    }
-
-    if (!RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath,
-        L"HTREE\\ROOT\\0"))
-    {
-        DPRINT1("Failed to create the instance path!\n");
-        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 0, 0, 0);
-    }
-
-    /* Report the device to the user-mode pnp manager */
-    IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
-        &IopRootDeviceNode->InstancePath);
-
-    IopRootDeviceNode->PhysicalDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
-    PnpRootDriverEntry(IopRootDriverObject, NULL);
-    IopRootDeviceNode->PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-    IopRootDriverObject->DriverExtension->AddDevice(
-        IopRootDriverObject,
-        IopRootDeviceNode->PhysicalDeviceObject);
-
-    /* Move information about devices detected by Freeloader to SYSTEM\CurrentControlSet\Root\ */
-    Status = IopUpdateRootKey();
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("IopUpdateRootKey() failed\n");
-        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
-    }
-}
-
 RTL_GENERIC_COMPARE_RESULTS
 NTAPI
 PiCompareInstancePath(IN PRTL_AVL_TABLE Table,
@@ -3605,6 +2958,49 @@ PpInitSystem(VOID)
     }
 }
 
+LONG IopNumberDeviceNodes;
+
+PDEVICE_NODE
+NTAPI
+PipAllocateDeviceNode(IN PDEVICE_OBJECT PhysicalDeviceObject)
+{
+    PDEVICE_NODE DeviceNode;
+    PAGED_CODE();
+    
+    /* Allocate it */
+    DeviceNode = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), 'donD');
+    if (!DeviceNode) return DeviceNode;
+    
+    /* Statistics */
+    InterlockedIncrement(&IopNumberDeviceNodes);
+    
+    /* Set it up */
+    RtlZeroMemory(DeviceNode, sizeof(DEVICE_NODE));
+    DeviceNode->InterfaceType = InterfaceTypeUndefined;
+    DeviceNode->BusNumber = -1;
+    DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
+    DeviceNode->ChildBusNumber = -1;
+    DeviceNode->ChildBusTypeIndex = -1;
+//    KeInitializeEvent(&DeviceNode->EnumerationMutex, SynchronizationEvent, TRUE);
+    InitializeListHead(&DeviceNode->DeviceArbiterList);
+    InitializeListHead(&DeviceNode->DeviceTranslatorList);
+    InitializeListHead(&DeviceNode->TargetDeviceNotify);
+    InitializeListHead(&DeviceNode->DockInfo.ListEntry);
+    InitializeListHead(&DeviceNode->PendedSetInterfaceState);
+    
+    /* Check if there is a PDO */
+    if (PhysicalDeviceObject)
+    {
+        /* Link it and remove the init flag */
+        DeviceNode->PhysicalDeviceObject = PhysicalDeviceObject;
+        ((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = DeviceNode;
+        PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+    }
+    
+    /* Return the node */
+    return DeviceNode;
+}
+
 /* PUBLIC FUNCTIONS **********************************************************/
 
 /*
@@ -3645,7 +3041,7 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
     case DevicePropertyBusTypeGuid:
         /* Sanity check */
         if ((DeviceNode->ChildBusTypeIndex != 0xFFFF) &&
-            (DeviceNode->ChildBusTypeIndex < IopBusTypeGuidList->GuidCount))
+            (DeviceNode->ChildBusTypeIndex < PnpBusTypeGuidList->GuidCount))
         {
             /* Return the GUID */
             *ResultLength = sizeof(GUID);
@@ -3658,7 +3054,7 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
 
             /* Copy the GUID */
             RtlCopyMemory(PropertyBuffer,
-                &(IopBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]),
+                &(PnpBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]),
                 sizeof(GUID));
             return STATUS_SUCCESS;
         }
@@ -3814,7 +3210,7 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
         Length = 0;
         if (DeviceNode->BootResources->Count != 0)
         {
-            Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
+            Length = IopCalculateResourceListSize(DeviceNode->BootResources);
         }
         Data = DeviceNode->BootResources;
         break;
@@ -3824,7 +3220,7 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
         Length = 0;
         if (DeviceNode->BootResources->Count != 0)
         {
-            Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
+            Length = IopCalculateResourceListSize(DeviceNode->BootResources);
         }
         Data = DeviceNode->BootResources;
         break;
index c328c80..f19f986 100644 (file)
@@ -42,6 +42,8 @@ IopNotifyPlugPlayNotification(
        PLIST_ENTRY ListEntry;
        PVOID NotificationStructure;
        BOOLEAN CallCurrentEntry;
+       UNICODE_STRING GuidString;
+       NTSTATUS Status;
 
        ASSERT(DeviceObject);
 
@@ -71,6 +73,13 @@ IopNotifyPlugPlayNotification(
                        RtlCopyMemory(&NotificationInfos->Event, Event, sizeof(GUID));
                        RtlCopyMemory(&NotificationInfos->InterfaceClassGuid, EventCategoryData1, sizeof(GUID));
                        NotificationInfos->SymbolicLinkName = (PUNICODE_STRING)EventCategoryData2;
+                       Status = RtlStringFromGUID(&NotificationInfos->InterfaceClassGuid, &GuidString);
+                       if (!NT_SUCCESS(Status))
+                       {
+                               KeReleaseGuardedMutex(&PnpNotifyListLock);
+                               ExFreePool(NotificationStructure);
+                               return;
+                       }
                        break;
                }
                case EventCategoryHardwareProfileChange:
@@ -125,12 +134,17 @@ IopNotifyPlugPlayNotification(
                ChangeEntry = CONTAINING_RECORD(ListEntry, PNP_NOTIFY_ENTRY, PnpNotifyList);
                CallCurrentEntry = FALSE;
 
+               if (ChangeEntry->EventCategory != EventCategory)
+               {
+                       ListEntry = ListEntry->Flink;
+                       continue;
+               }
+
                switch (EventCategory)
                {
                        case EventCategoryDeviceInterfaceChange:
                        {
-                               if (ChangeEntry->EventCategory == EventCategory
-                                       && RtlCompareUnicodeString(&ChangeEntry->Guid, (PUNICODE_STRING)EventCategoryData1, FALSE) == 0)
+                               if (RtlCompareUnicodeString(&ChangeEntry->Guid, &GuidString, FALSE) == 0)
                                {
                                        CallCurrentEntry = TRUE;
                                }
@@ -174,6 +188,8 @@ IopNotifyPlugPlayNotification(
        }
        KeReleaseGuardedMutex(&PnpNotifyListLock);
        ExFreePoolWithTag(NotificationStructure, TAG_PNP_NOTIFY);
+       if (EventCategory == EventCategoryDeviceInterfaceChange)
+               RtlFreeUnicodeString(&GuidString);
 }
 
 /* PUBLIC FUNCTIONS **********************************************************/
index c75e566..f69bce0 100644 (file)
 NTSTATUS
 NTAPI
 IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
+                       IN ULONG CreateOptions,
                        OUT PHANDLE Handle);
 
-NTSTATUS
-IopAssignDeviceResources(
-   IN PDEVICE_NODE DeviceNode,
-   OUT ULONG *pRequiredSize);
-
 NTSTATUS
 IopSetDeviceInstanceData(HANDLE InstanceKey,
                          PDEVICE_NODE DeviceNode);
 
-NTSTATUS
-IopTranslateDeviceResources(
-   IN PDEVICE_NODE DeviceNode,
-   IN ULONG RequiredSize);
-
 NTSTATUS
 IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
                                 PVOID Context);
 
-NTSTATUS
-IopUpdateResourceMapForPnPDevice(
-   IN PDEVICE_NODE DeviceNode);
-
 NTSTATUS
 IopDetectResourceConflict(
    IN PCM_RESOURCE_LIST ResourceList);
@@ -188,6 +175,11 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
     /* We don't send IRP_MN_START_DEVICE */
     IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
 
+    /* We need to get device IDs */
+#if 0
+    IopDeviceNodeSetFlag(DeviceNode, DNF_NEED_QUERY_IDS);
+#endif
+
     /* This is a legacy driver for this device */
     IopDeviceNodeSetFlag(DeviceNode, DNF_LEGACY_DRIVER);
 
@@ -196,7 +188,7 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
     IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent);
 
     /* Open a handle to the instance path key */
-    Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, &InstanceKey);
+    Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey);
     if (!NT_SUCCESS(Status))
         return Status;
 
@@ -257,38 +249,29 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
     if (DeviceNode->BootResources)
        IopDeviceNodeSetFlag(DeviceNode, DNF_HAS_BOOT_CONFIG);
 
-    if (DeviceNode->ResourceRequirements)
-       IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_REPORTED);
-    else
+    if (!DeviceNode->ResourceRequirements && !DeviceNode->BootResources)
        IopDeviceNodeSetFlag(DeviceNode, DNF_NO_RESOURCE_REQUIRED);
 
     /* Write the resource information to the registry */
     IopSetDeviceInstanceData(InstanceKey, DeviceNode);
 
-    /* Close the instance key handle */
-    ZwClose(InstanceKey);
-
     /* If the caller didn't get the resources assigned for us, do it now */
     if (!ResourceAssigned)
     {
-       IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
-       Status = IopAssignDeviceResources(DeviceNode, &RequiredLength);
-       if (NT_SUCCESS(Status))
-       {
-          Status = IopTranslateDeviceResources(DeviceNode, RequiredLength);
-          if (NT_SUCCESS(Status))
-              Status = IopUpdateResourceMapForPnPDevice(DeviceNode);
-       }
-       IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
+       Status = IopAssignDeviceResources(DeviceNode);
 
        /* See if we failed */
        if (!NT_SUCCESS(Status))
        {
            DPRINT("Assigning resources failed: 0x%x\n", Status);
+           ZwClose(InstanceKey);
            return Status;
        }
     }
 
+    /* Close the instance key handle */
+    ZwClose(InstanceKey);
+
     /* Report the device's enumeration to umpnpmgr */
     IopQueueTargetDeviceEvent(&GUID_DEVICE_ENUMERATED,
                               &DeviceNode->InstancePath);
diff --git a/ntoskrnl/io/pnpmgr/pnpres.c b/ntoskrnl/io/pnpmgr/pnpres.c
new file mode 100644 (file)
index 0000000..8814890
--- /dev/null
@@ -0,0 +1,1159 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/io/pnpmgr/pnpres.c
+ * PURPOSE:         Resource handling code
+ * PROGRAMMERS:     Cameron Gutman (cameron.gutman@reactos.org)
+ *                  ReactOS Portable Systems Group
+ */
+
+#include <ntoskrnl.h>
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS
+IopDetectResourceConflict(
+   IN PCM_RESOURCE_LIST ResourceList,
+   IN BOOLEAN Silent,
+   OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor);
+
+ULONG
+NTAPI
+IopCalculateResourceListSize(
+   IN PCM_RESOURCE_LIST ResourceList)
+{
+   ULONG Size, i, j;
+   PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
+
+   Size = FIELD_OFFSET(CM_RESOURCE_LIST, List);
+   for (i = 0; i < ResourceList->Count; i++)
+   {
+      pPartialResourceList = &ResourceList->List[i].PartialResourceList;
+      Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors) +
+              pPartialResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+      for (j = 0; j < pPartialResourceList->Count; j++)
+      {
+         if (pPartialResourceList->PartialDescriptors[j].Type == CmResourceTypeDeviceSpecific)
+             Size += pPartialResourceList->PartialDescriptors[j].u.DeviceSpecificData.DataSize;
+      }
+   }
+
+   return Size;
+}
+
+static
+BOOLEAN
+IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
+{
+   CM_RESOURCE_LIST CmList;
+   NTSTATUS Status;
+
+   CmList.Count = 1;
+   CmList.List[0].InterfaceType = InterfaceTypeUndefined;
+   CmList.List[0].BusNumber = 0;
+   CmList.List[0].PartialResourceList.Version = 1;
+   CmList.List[0].PartialResourceList.Revision = 1;
+   CmList.List[0].PartialResourceList.Count = 1;
+   CmList.List[0].PartialResourceList.PartialDescriptors[0] = *CmDesc;
+
+   Status = IopDetectResourceConflict(&CmList, TRUE, ConflictingDescriptor);
+   if (Status == STATUS_CONFLICTING_ADDRESSES)
+       return TRUE;
+
+   return FALSE;
+}
+
+static
+BOOLEAN
+IopFindBusNumberResource(
+   IN PIO_RESOURCE_DESCRIPTOR IoDesc,
+   OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
+{
+   ULONG Start;
+   CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc;
+
+   ASSERT(IoDesc->Type == CmDesc->Type);
+   ASSERT(IoDesc->Type == CmResourceTypeBusNumber);
+
+   for (Start = IoDesc->u.BusNumber.MinBusNumber;
+        Start < IoDesc->u.BusNumber.MaxBusNumber;
+        Start++)
+   {
+        CmDesc->u.BusNumber.Length = IoDesc->u.BusNumber.Length;
+        CmDesc->u.BusNumber.Start = Start;
+
+        if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc))
+        {
+            Start += ConflictingDesc.u.BusNumber.Start + ConflictingDesc.u.BusNumber.Length;
+        }
+        else
+        {
+            return TRUE;
+        }
+   }
+
+   return FALSE;
+}
+
+static
+BOOLEAN
+IopFindMemoryResource(
+   IN PIO_RESOURCE_DESCRIPTOR IoDesc,
+   OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
+{
+   ULONGLONG Start;
+   CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc;
+
+   ASSERT(IoDesc->Type == CmDesc->Type);
+   ASSERT(IoDesc->Type == CmResourceTypeMemory);
+
+   for (Start = IoDesc->u.Memory.MinimumAddress.QuadPart;
+        Start < IoDesc->u.Memory.MaximumAddress.QuadPart;
+        Start++)
+   {
+        CmDesc->u.Memory.Length = IoDesc->u.Memory.Length;
+        CmDesc->u.Memory.Start.QuadPart = Start;
+
+        if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc))
+        {
+            Start += ConflictingDesc.u.Memory.Start.QuadPart + ConflictingDesc.u.Memory.Length;
+        }
+        else
+        {
+            return TRUE;
+        }
+   }
+
+   return FALSE;
+}
+
+static
+BOOLEAN
+IopFindPortResource(
+   IN PIO_RESOURCE_DESCRIPTOR IoDesc,
+   OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
+{
+   ULONGLONG Start;
+   CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc;
+
+   ASSERT(IoDesc->Type == CmDesc->Type);
+   ASSERT(IoDesc->Type == CmResourceTypePort);
+
+   for (Start = IoDesc->u.Port.MinimumAddress.QuadPart;
+        Start < IoDesc->u.Port.MaximumAddress.QuadPart;
+        Start++)
+   {
+        CmDesc->u.Port.Length = IoDesc->u.Port.Length;
+        CmDesc->u.Port.Start.QuadPart = Start;
+
+        if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc))
+        {
+            Start += ConflictingDesc.u.Port.Start.QuadPart + ConflictingDesc.u.Port.Length;
+        }
+        else
+        {
+            return TRUE;
+        }
+   }
+
+   return FALSE;
+}
+
+static
+BOOLEAN
+IopFindDmaResource(
+   IN PIO_RESOURCE_DESCRIPTOR IoDesc,
+   OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
+{
+   ULONG Channel;
+
+   ASSERT(IoDesc->Type == CmDesc->Type);
+   ASSERT(IoDesc->Type == CmResourceTypeDma);
+
+   for (Channel = IoDesc->u.Dma.MinimumChannel;
+        Channel < IoDesc->u.Dma.MaximumChannel;
+        Channel++)
+   {
+        CmDesc->u.Dma.Channel = Channel;
+        CmDesc->u.Dma.Port = 0;
+
+        if (!IopCheckDescriptorForConflict(CmDesc, NULL))
+            return TRUE;
+   }
+
+   return FALSE;
+}
+
+static
+BOOLEAN
+IopFindInterruptResource(
+   IN PIO_RESOURCE_DESCRIPTOR IoDesc,
+   OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
+{
+   ULONG Vector;
+
+   ASSERT(IoDesc->Type == CmDesc->Type);
+   ASSERT(IoDesc->Type == CmResourceTypeInterrupt);
+
+   for (Vector = IoDesc->u.Interrupt.MinimumVector;
+        Vector < IoDesc->u.Interrupt.MaximumVector;
+        Vector++)
+   {
+        CmDesc->u.Interrupt.Vector = Vector;
+        CmDesc->u.Interrupt.Level = Vector;
+        CmDesc->u.Interrupt.Affinity = (KAFFINITY)-1;
+
+        if (!IopCheckDescriptorForConflict(CmDesc, NULL))
+            return TRUE;
+   }
+
+   return FALSE;
+}
+
+static
+NTSTATUS
+IopCreateResourceListFromRequirements(
+   IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList,
+   OUT PCM_RESOURCE_LIST *ResourceList)
+{
+   ULONG i, ii, Size;
+   PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc;
+
+   Size = FIELD_OFFSET(CM_RESOURCE_LIST, List);
+   for (i = 0; i < RequirementsList->AlternativeLists; i++)
+   {
+      PIO_RESOURCE_LIST ResList = &RequirementsList->List[i];
+      Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors)
+        + ResList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+   }
+
+   *ResourceList = ExAllocatePool(PagedPool, Size);
+   if (!*ResourceList)
+       return STATUS_INSUFFICIENT_RESOURCES;
+
+   (*ResourceList)->Count = 1;
+   (*ResourceList)->List[0].BusNumber = RequirementsList->BusNumber;
+   (*ResourceList)->List[0].InterfaceType = RequirementsList->InterfaceType;
+   (*ResourceList)->List[0].PartialResourceList.Version = 1;
+   (*ResourceList)->List[0].PartialResourceList.Revision = 1;
+   (*ResourceList)->List[0].PartialResourceList.Count = 0;
+
+   ResDesc = &(*ResourceList)->List[0].PartialResourceList.PartialDescriptors[0];
+
+   for (i = 0; i < RequirementsList->AlternativeLists; i++)
+   {
+      PIO_RESOURCE_LIST ResList = &RequirementsList->List[i];
+      for (ii = 0; ii < ResList->Count; ii++)
+      {
+         PIO_RESOURCE_DESCRIPTOR ReqDesc = &ResList->Descriptors[ii];
+
+         /* FIXME: Handle alternate ranges */
+         if (ReqDesc->Option == IO_RESOURCE_ALTERNATIVE)
+             continue;
+
+         ResDesc->Type = ReqDesc->Type;
+         ResDesc->Flags = ReqDesc->Flags;
+         ResDesc->ShareDisposition = ReqDesc->ShareDisposition;
+
+         switch (ReqDesc->Type)
+         {
+            case CmResourceTypeInterrupt:
+              if (!IopFindInterruptResource(ReqDesc, ResDesc))
+              {
+                  DPRINT1("Failed to find an available interrupt resource (0x%x to 0x%x)\n",
+                           ReqDesc->u.Interrupt.MinimumVector, ReqDesc->u.Interrupt.MaximumVector);
+
+                  if (ReqDesc->Option == 0)
+                  {
+                      ExFreePool(*ResourceList);
+                      return STATUS_CONFLICTING_ADDRESSES;
+                  }
+              }
+              break;
+
+            case CmResourceTypePort:
+              if (!IopFindPortResource(ReqDesc, ResDesc))
+              {
+                  DPRINT1("Failed to find an available port resource (0x%x to 0x%x length: 0x%x)\n",
+                          ReqDesc->u.Port.MinimumAddress.QuadPart, ReqDesc->u.Port.MaximumAddress.QuadPart,
+                          ReqDesc->u.Port.Length);
+
+                  if (ReqDesc->Option == 0)
+                  {
+                      ExFreePool(*ResourceList);
+                      return STATUS_CONFLICTING_ADDRESSES;
+                  }
+              }
+              break;
+
+            case CmResourceTypeMemory:
+              if (!IopFindMemoryResource(ReqDesc, ResDesc))
+              {
+                  DPRINT1("Failed to find an available memory resource (0x%x to 0x%x length: 0x%x)\n",
+                          ReqDesc->u.Memory.MinimumAddress.QuadPart, ReqDesc->u.Memory.MaximumAddress.QuadPart,
+                          ReqDesc->u.Memory.Length);
+
+                  if (ReqDesc->Option == 0)
+                  {
+                      ExFreePool(*ResourceList);
+                      return STATUS_CONFLICTING_ADDRESSES;
+                  }
+              }
+              break;
+
+            case CmResourceTypeBusNumber:
+              if (!IopFindBusNumberResource(ReqDesc, ResDesc))
+              {
+                  DPRINT1("Failed to find an available bus number resource (0x%x to 0x%x length: 0x%x)\n",
+                          ReqDesc->u.BusNumber.MinBusNumber, ReqDesc->u.BusNumber.MaxBusNumber,
+                          ReqDesc->u.BusNumber.Length);
+
+                  if (ReqDesc->Option == 0)
+                  {
+                      ExFreePool(*ResourceList);
+                      return STATUS_CONFLICTING_ADDRESSES;
+                  }
+              }
+              break;
+
+            case CmResourceTypeDma:
+              if (!IopFindDmaResource(ReqDesc, ResDesc))
+              {
+                  DPRINT1("Failed to find an available dma resource (0x%x to 0x%x)\n",
+                          ReqDesc->u.Dma.MinimumChannel, ReqDesc->u.Dma.MaximumChannel);
+
+                  if (ReqDesc->Option == 0)
+                  {
+                      ExFreePool(*ResourceList);
+                      return STATUS_CONFLICTING_ADDRESSES;
+                  }
+              }
+              break;
+
+            default:
+              DPRINT1("Unsupported resource type: %x\n", ReqDesc->Type);
+              break;
+         }
+
+         (*ResourceList)->List[0].PartialResourceList.Count++;
+         ResDesc++;
+      }
+   }
+
+   return STATUS_SUCCESS;
+}
+
+static
+BOOLEAN
+IopCheckResourceDescriptor(
+   IN PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc,
+   IN PCM_RESOURCE_LIST ResourceList,
+   IN BOOLEAN Silent,
+   OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
+{
+   ULONG i, ii;
+   BOOLEAN Result = FALSE;
+
+   if (ResDesc->ShareDisposition == CmResourceShareShared)
+       return FALSE;
+
+   for (i = 0; i < ResourceList->Count; i++)
+   {
+      PCM_PARTIAL_RESOURCE_LIST ResList = &ResourceList->List[i].PartialResourceList;
+      for (ii = 0; ii < ResList->Count; ii++)
+      {
+         PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc2 = &ResList->PartialDescriptors[ii];
+
+         /* We don't care about shared resources */
+         if (ResDesc->ShareDisposition == CmResourceShareShared &&
+             ResDesc2->ShareDisposition == CmResourceShareShared)
+             continue;
+
+         /* Make sure we're comparing the same types */
+         if (ResDesc->Type != ResDesc2->Type)
+             continue;
+
+         switch (ResDesc->Type)
+         {
+             case CmResourceTypeMemory:
+                 if ((ResDesc->u.Memory.Start.QuadPart < ResDesc2->u.Memory.Start.QuadPart &&
+                      ResDesc->u.Memory.Start.QuadPart + ResDesc->u.Memory.Length >
+                      ResDesc2->u.Memory.Start.QuadPart) || (ResDesc2->u.Memory.Start.QuadPart <
+                      ResDesc->u.Memory.Start.QuadPart && ResDesc2->u.Memory.Start.QuadPart +
+                      ResDesc2->u.Memory.Length > ResDesc->u.Memory.Start.QuadPart))
+                 {
+                      if (!Silent)
+                      {
+                          DPRINT1("Resource conflict: Memory (0x%x to 0x%x vs. 0x%x to 0x%x)\n",
+                                  ResDesc->u.Memory.Start.QuadPart, ResDesc->u.Memory.Start.QuadPart +
+                                  ResDesc->u.Memory.Length, ResDesc2->u.Memory.Start.QuadPart,
+                                  ResDesc2->u.Memory.Start.QuadPart + ResDesc2->u.Memory.Length);
+                      }
+
+                      Result = TRUE;
+
+                      goto ByeBye;
+                 }
+                 break;
+
+             case CmResourceTypePort:
+                 if ((ResDesc->u.Port.Start.QuadPart < ResDesc2->u.Port.Start.QuadPart &&
+                      ResDesc->u.Port.Start.QuadPart + ResDesc->u.Port.Length >
+                      ResDesc2->u.Port.Start.QuadPart) || (ResDesc2->u.Port.Start.QuadPart <
+                      ResDesc->u.Port.Start.QuadPart && ResDesc2->u.Port.Start.QuadPart +
+                      ResDesc2->u.Port.Length > ResDesc->u.Port.Start.QuadPart))
+                 {
+                      if (!Silent)
+                      {
+                          DPRINT1("Resource conflict: Port (0x%x to 0x%x vs. 0x%x to 0x%x)\n",
+                                  ResDesc->u.Port.Start.QuadPart, ResDesc->u.Port.Start.QuadPart +
+                                  ResDesc->u.Port.Length, ResDesc2->u.Port.Start.QuadPart,
+                                  ResDesc2->u.Port.Start.QuadPart + ResDesc2->u.Port.Length);
+                      }
+
+                      Result = TRUE;
+
+                      goto ByeBye;
+                 }
+                 break;
+
+             case CmResourceTypeInterrupt:
+                 if (ResDesc->u.Interrupt.Vector == ResDesc2->u.Interrupt.Vector)
+                 {
+                      if (!Silent)
+                      {
+                          DPRINT1("Resource conflict: IRQ (0x%x 0x%x vs. 0x%x 0x%x)\n",
+                                  ResDesc->u.Interrupt.Vector, ResDesc->u.Interrupt.Level,
+                                  ResDesc2->u.Interrupt.Vector, ResDesc2->u.Interrupt.Level);
+                      }
+
+                      Result = TRUE;
+
+                      goto ByeBye;
+                 }
+                 break;
+
+             case CmResourceTypeBusNumber:
+                 if ((ResDesc->u.BusNumber.Start < ResDesc2->u.BusNumber.Start &&
+                      ResDesc->u.BusNumber.Start + ResDesc->u.BusNumber.Length >
+                      ResDesc2->u.BusNumber.Start) || (ResDesc2->u.BusNumber.Start <
+                      ResDesc->u.BusNumber.Start && ResDesc2->u.BusNumber.Start +
+                      ResDesc2->u.BusNumber.Length > ResDesc->u.BusNumber.Start))
+                 {
+                      if (!Silent)
+                      {
+                          DPRINT1("Resource conflict: Bus number (0x%x to 0x%x vs. 0x%x to 0x%x)\n",
+                                  ResDesc->u.BusNumber.Start, ResDesc->u.BusNumber.Start +
+                                  ResDesc->u.BusNumber.Length, ResDesc2->u.BusNumber.Start,
+                                  ResDesc2->u.BusNumber.Start + ResDesc2->u.BusNumber.Length);
+                      }
+
+                      Result = TRUE;
+
+                      goto ByeBye;
+                 }
+                 break;
+
+             case CmResourceTypeDma:
+                 if (ResDesc->u.Dma.Channel == ResDesc2->u.Dma.Channel)
+                 {
+                     if (!Silent)
+                     {
+                         DPRINT1("Resource conflict: Dma (0x%x 0x%x vs. 0x%x 0x%x)\n",
+                                 ResDesc->u.Dma.Channel, ResDesc->u.Dma.Port,
+                                 ResDesc2->u.Dma.Channel, ResDesc2->u.Dma.Port);
+                     }
+
+                     Result = TRUE;
+
+                     goto ByeBye;
+                 }
+                 break;
+         }
+      }
+   }
+
+ByeBye:
+
+   if (Result && ConflictingDescriptor)
+   {
+       RtlCopyMemory(ConflictingDescriptor,
+                     ResDesc,
+                     sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
+   }
+
+   return Result;
+}
+
+static
+NTSTATUS
+IopUpdateControlKeyWithResources(IN PDEVICE_NODE DeviceNode)
+{
+   UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT);
+   UNICODE_STRING Control = RTL_CONSTANT_STRING(L"Control");
+   UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"AllocConfig");
+   HANDLE EnumKey, InstanceKey, ControlKey;
+   NTSTATUS Status;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+
+   /* Open the Enum key */
+   Status = IopOpenRegistryKeyEx(&EnumKey, NULL, &EnumRoot, KEY_ENUMERATE_SUB_KEYS);
+   if (!NT_SUCCESS(Status))
+       return Status;
+
+   /* Open the instance key (eg. Root\PNP0A03) */
+   Status = IopOpenRegistryKeyEx(&InstanceKey, EnumKey, &DeviceNode->InstancePath, KEY_ENUMERATE_SUB_KEYS);
+   ZwClose(EnumKey);
+
+   if (!NT_SUCCESS(Status))
+       return Status;
+
+   /* Create/Open the Control key */
+   InitializeObjectAttributes(&ObjectAttributes,
+                              &Control,
+                              OBJ_CASE_INSENSITIVE,
+                              InstanceKey,
+                              NULL);
+   Status = ZwCreateKey(&ControlKey,
+                        KEY_SET_VALUE,
+                        &ObjectAttributes,
+                        0,
+                        NULL,
+                        REG_OPTION_VOLATILE,
+                        NULL);
+   ZwClose(InstanceKey);
+
+   if (!NT_SUCCESS(Status))
+       return Status;
+
+   /* Write the resource list */
+   Status = ZwSetValueKey(ControlKey,
+                          &ValueName,
+                          0,
+                          REG_RESOURCE_LIST,
+                          DeviceNode->ResourceList,
+                          IopCalculateResourceListSize(DeviceNode->ResourceList));
+   ZwClose(ControlKey);
+
+   if (!NT_SUCCESS(Status))
+       return Status; 
+
+   return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+IopFilterResourceRequirements(IN PDEVICE_NODE DeviceNode)
+{
+   IO_STACK_LOCATION Stack;
+   IO_STATUS_BLOCK IoStatusBlock;
+   NTSTATUS Status;
+
+   DPRINT("Sending IRP_MN_FILTER_RESOURCE_REQUIREMENTS to device stack\n");
+
+   Stack.Parameters.FilterResourceRequirements.IoResourceRequirementList = DeviceNode->ResourceRequirements;
+   Status = IopInitiatePnpIrp(
+      DeviceNode->PhysicalDeviceObject,
+      &IoStatusBlock,
+      IRP_MN_FILTER_RESOURCE_REQUIREMENTS,
+      &Stack);
+   if (!NT_SUCCESS(Status) && Status != STATUS_NOT_SUPPORTED)
+   {
+      DPRINT("IopInitiatePnpIrp(IRP_MN_FILTER_RESOURCE_REQUIREMENTS) failed\n");
+      return Status;
+   }
+   else if (NT_SUCCESS(Status))
+   {
+      DeviceNode->ResourceRequirements = (PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information;
+   }
+
+   return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2Key)
+{
+  NTSTATUS Status;
+  ULONG Disposition;
+  HANDLE PnpMgrLevel1, PnpMgrLevel2, ResourceMapKey;
+  UNICODE_STRING KeyName;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+
+  RtlInitUnicodeString(&KeyName,
+                      L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &KeyName,
+                            OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+                            0,
+                            NULL);
+  Status = ZwCreateKey(&ResourceMapKey,
+                      KEY_ALL_ACCESS,
+                      &ObjectAttributes,
+                      0,
+                      NULL,
+                      REG_OPTION_VOLATILE,
+                      &Disposition);
+  if (!NT_SUCCESS(Status))
+      return Status;
+
+  RtlInitUnicodeString(&KeyName, Level1Key);
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &KeyName,
+                            OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+                            ResourceMapKey,
+                            NULL);
+  Status = ZwCreateKey(&PnpMgrLevel1,
+                       KEY_ALL_ACCESS,
+                       &ObjectAttributes,
+                       0,
+                       NULL,
+                       REG_OPTION_VOLATILE,
+                       &Disposition);
+  ZwClose(ResourceMapKey);
+  if (!NT_SUCCESS(Status))
+      return Status;
+
+  RtlInitUnicodeString(&KeyName, Level2Key);
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &KeyName,
+                            OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+                            PnpMgrLevel1,
+                            NULL);
+  Status = ZwCreateKey(&PnpMgrLevel2,
+                       KEY_ALL_ACCESS,
+                       &ObjectAttributes,
+                       0,
+                       NULL,
+                       REG_OPTION_VOLATILE,
+                       &Disposition);
+  ZwClose(PnpMgrLevel1);
+  if (!NT_SUCCESS(Status))
+      return Status;
+
+  if (DeviceNode->ResourceList)
+  {
+      WCHAR NameBuff[256];
+      UNICODE_STRING NameU;
+      UNICODE_STRING Suffix;
+      ULONG OldLength;
+
+      ASSERT(DeviceNode->ResourceListTranslated);
+
+      NameU.Buffer = NameBuff;
+      NameU.Length = 0;
+      NameU.MaximumLength = 256 * sizeof(WCHAR);
+
+      Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
+                                   DevicePropertyPhysicalDeviceObjectName,
+                                   NameU.MaximumLength,
+                                   NameU.Buffer,
+                                   &OldLength);
+      ASSERT(Status == STATUS_SUCCESS);
+
+      NameU.Length = (USHORT)OldLength;
+
+      RtlInitUnicodeString(&Suffix, L".Raw");
+      RtlAppendUnicodeStringToString(&NameU, &Suffix);
+
+      Status = ZwSetValueKey(PnpMgrLevel2,
+                             &NameU,
+                             0,
+                             REG_RESOURCE_LIST,
+                             DeviceNode->ResourceList,
+                             IopCalculateResourceListSize(DeviceNode->ResourceList));
+      if (!NT_SUCCESS(Status))
+      {
+          ZwClose(PnpMgrLevel2);
+          return Status;
+      }
+
+      /* "Remove" the suffix by setting the length back to what it used to be */
+      NameU.Length = (USHORT)OldLength;
+
+      RtlInitUnicodeString(&Suffix, L".Translated");
+      RtlAppendUnicodeStringToString(&NameU, &Suffix);
+
+      Status = ZwSetValueKey(PnpMgrLevel2,
+                             &NameU,
+                             0,
+                             REG_RESOURCE_LIST,
+                             DeviceNode->ResourceListTranslated,
+                             IopCalculateResourceListSize(DeviceNode->ResourceListTranslated));
+      ZwClose(PnpMgrLevel2);
+      if (!NT_SUCCESS(Status))
+          return Status;
+  }
+  else
+  {
+      ZwClose(PnpMgrLevel2);
+  }
+
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS
+IopUpdateResourceMapForPnPDevice(IN PDEVICE_NODE DeviceNode)
+{
+  return IopUpdateResourceMap(DeviceNode, L"PnP Manager", L"PnpManager");
+}
+
+static
+NTSTATUS
+IopTranslateDeviceResources(
+   IN PDEVICE_NODE DeviceNode)
+{
+   PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
+   PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated;
+   ULONG i, j, ListSize;
+   NTSTATUS Status;
+
+   if (!DeviceNode->ResourceList)
+   {
+      DeviceNode->ResourceListTranslated = NULL;
+      return STATUS_SUCCESS;
+   }
+
+   /* That's easy to translate a resource list. Just copy the
+    * untranslated one and change few fields in the copy
+    */
+   ListSize = IopCalculateResourceListSize(DeviceNode->ResourceList);
+
+   DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, ListSize);
+   if (!DeviceNode->ResourceListTranslated)
+   {
+      Status =STATUS_NO_MEMORY;
+      goto cleanup;
+   }
+   RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, ListSize);
+
+   for (i = 0; i < DeviceNode->ResourceList->Count; i++)
+   {
+      pPartialResourceList = &DeviceNode->ResourceList->List[i].PartialResourceList;
+      for (j = 0; j < pPartialResourceList->Count; j++)
+      {
+         DescriptorRaw = &pPartialResourceList->PartialDescriptors[j];
+         DescriptorTranslated = &DeviceNode->ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j];
+         switch (DescriptorRaw->Type)
+         {
+            case CmResourceTypePort:
+            {
+               ULONG AddressSpace = 1; /* IO space */
+               if (!HalTranslateBusAddress(
+                  DeviceNode->ResourceList->List[i].InterfaceType,
+                  DeviceNode->ResourceList->List[i].BusNumber,
+                  DescriptorRaw->u.Port.Start,
+                  &AddressSpace,
+                  &DescriptorTranslated->u.Port.Start))
+               {
+                  Status = STATUS_UNSUCCESSFUL;
+                  goto cleanup;
+               }
+               break;
+            }
+            case CmResourceTypeInterrupt:
+            {
+               DescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector(
+                  DeviceNode->ResourceList->List[i].InterfaceType,
+                  DeviceNode->ResourceList->List[i].BusNumber,
+                  DescriptorRaw->u.Interrupt.Level,
+                  DescriptorRaw->u.Interrupt.Vector,
+                  (PKIRQL)&DescriptorTranslated->u.Interrupt.Level,
+                  &DescriptorRaw->u.Interrupt.Affinity);
+               break;
+            }
+            case CmResourceTypeMemory:
+            {
+               ULONG AddressSpace = 0; /* Memory space */
+               if (!HalTranslateBusAddress(
+                  DeviceNode->ResourceList->List[i].InterfaceType,
+                  DeviceNode->ResourceList->List[i].BusNumber,
+                  DescriptorRaw->u.Memory.Start,
+                  &AddressSpace,
+                  &DescriptorTranslated->u.Memory.Start))
+               {
+                  Status = STATUS_UNSUCCESSFUL;
+                  goto cleanup;
+               }
+            }
+
+            case CmResourceTypeDma:
+            case CmResourceTypeBusNumber:
+            case CmResourceTypeDeviceSpecific:
+               /* Nothing to do */
+               break;
+            default:
+               DPRINT1("Unknown resource descriptor type 0x%x\n", DescriptorRaw->Type);
+               Status = STATUS_NOT_IMPLEMENTED;
+               goto cleanup;
+         }
+      }
+   }
+   return STATUS_SUCCESS;
+
+cleanup:
+   /* Yes! Also delete ResourceList because ResourceList and
+    * ResourceListTranslated should be a pair! */
+   ExFreePool(DeviceNode->ResourceList);
+   DeviceNode->ResourceList = NULL;
+   if (DeviceNode->ResourceListTranslated)
+   {
+      ExFreePool(DeviceNode->ResourceListTranslated);
+      DeviceNode->ResourceList = NULL;
+   }
+   return Status;
+}
+
+NTSTATUS
+NTAPI
+IopAssignDeviceResources(
+   IN PDEVICE_NODE DeviceNode)
+{
+   NTSTATUS Status;
+   ULONG ListSize;
+
+   IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
+
+   Status = IopFilterResourceRequirements(DeviceNode);
+   if (!NT_SUCCESS(Status))
+       goto ByeBye;
+
+   if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements)
+   {
+      DeviceNode->Flags |= DNF_NO_RESOURCE_REQUIRED;
+      DeviceNode->Flags &= ~DNF_ASSIGNING_RESOURCES;
+
+      /* No resource needed for this device */
+      DeviceNode->ResourceList = NULL;
+      DeviceNode->ResourceListTranslated = NULL;
+
+      return STATUS_SUCCESS;
+   }
+
+   /* Fill DeviceNode->ResourceList
+    * FIXME: the PnP arbiter should go there!
+    * Actually, use the BootResources if provided, else the resource requirements
+    */
+
+   if (DeviceNode->BootResources)
+   {
+      ListSize = IopCalculateResourceListSize(DeviceNode->BootResources);
+
+      DeviceNode->ResourceList = ExAllocatePool(PagedPool, ListSize);
+      if (!DeviceNode->ResourceList)
+      {
+         Status = STATUS_NO_MEMORY;
+         goto ByeBye;
+      }
+      RtlCopyMemory(DeviceNode->ResourceList, DeviceNode->BootResources, ListSize);
+
+      Status = IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL);
+      if (NT_SUCCESS(Status) || !DeviceNode->ResourceRequirements)
+      {
+          if (!NT_SUCCESS(Status) && !DeviceNode->ResourceRequirements)
+          {
+              DPRINT1("Using conflicting boot resources because no requirements were supplied!\n");
+          }
+
+          goto Finish;
+      }
+      else
+      {
+          DPRINT1("Boot resources for %wZ cause a resource conflict!\n", &DeviceNode->InstancePath);
+          ExFreePool(DeviceNode->ResourceList);
+      }
+   }
+
+   Status = IopCreateResourceListFromRequirements(DeviceNode->ResourceRequirements,
+                                                  &DeviceNode->ResourceList);
+   if (!NT_SUCCESS(Status))
+       goto ByeBye;
+
+   Status = IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL);
+   if (!NT_SUCCESS(Status))
+       goto ByeBye;
+
+Finish:
+   Status = IopTranslateDeviceResources(DeviceNode);
+   if (!NT_SUCCESS(Status))
+       goto ByeBye;
+
+   Status = IopUpdateResourceMapForPnPDevice(DeviceNode);
+   if (!NT_SUCCESS(Status))
+       goto ByeBye;
+
+   Status = IopUpdateControlKeyWithResources(DeviceNode);
+   if (!NT_SUCCESS(Status))
+       goto ByeBye;
+
+   IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED);
+
+   IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
+
+   return STATUS_SUCCESS;
+
+ByeBye:
+   if (DeviceNode->ResourceList)
+   {
+      ExFreePool(DeviceNode->ResourceList);
+      DeviceNode->ResourceList = NULL;
+   }
+
+   DeviceNode->ResourceListTranslated = NULL;
+
+   IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
+
+   return Status;
+}
+
+static
+BOOLEAN
+IopCheckForResourceConflict(
+   IN PCM_RESOURCE_LIST ResourceList1,
+   IN PCM_RESOURCE_LIST ResourceList2,
+   IN BOOLEAN Silent,
+   OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
+{
+   ULONG i, ii;
+   BOOLEAN Result = FALSE;
+
+   for (i = 0; i < ResourceList1->Count; i++)
+   {
+      PCM_PARTIAL_RESOURCE_LIST ResList = &ResourceList1->List[i].PartialResourceList;
+      for (ii = 0; ii < ResList->Count; ii++)
+      {
+         PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc = &ResList->PartialDescriptors[ii];
+
+         Result = IopCheckResourceDescriptor(ResDesc,
+                                             ResourceList2,
+                                             Silent,
+                                             ConflictingDescriptor);
+         if (Result) goto ByeBye;
+      }
+   }
+
+        
+ByeBye:
+
+   return Result;
+}
+
+NTSTATUS
+IopDetectResourceConflict(
+   IN PCM_RESOURCE_LIST ResourceList,
+   IN BOOLEAN Silent,
+   OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
+{
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   UNICODE_STRING KeyName;
+   HANDLE ResourceMapKey = INVALID_HANDLE_VALUE, ChildKey2 = INVALID_HANDLE_VALUE, ChildKey3 = INVALID_HANDLE_VALUE;
+   ULONG KeyInformationLength, RequiredLength, KeyValueInformationLength, KeyNameInformationLength;
+   PKEY_BASIC_INFORMATION KeyInformation;
+   PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
+   PKEY_VALUE_BASIC_INFORMATION KeyNameInformation;
+   ULONG ChildKeyIndex1 = 0, ChildKeyIndex2 = 0, ChildKeyIndex3 = 0;
+   NTSTATUS Status;
+
+   RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
+   InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, 0, NULL);
+   Status = ZwOpenKey(&ResourceMapKey, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes);
+   if (!NT_SUCCESS(Status))
+   {
+      /* The key is missing which means we are the first device */
+      return STATUS_SUCCESS;
+   }
+
+   while (TRUE)
+   {
+      Status = ZwEnumerateKey(ResourceMapKey,
+                              ChildKeyIndex1,
+                              KeyBasicInformation,
+                              NULL,
+                              0,
+                              &RequiredLength);
+      if (Status == STATUS_NO_MORE_ENTRIES)
+          break;
+      else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
+      {
+          KeyInformationLength = RequiredLength;
+          KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength);
+          if (!KeyInformation)
+          {
+              Status = STATUS_INSUFFICIENT_RESOURCES;
+              goto cleanup;
+          }
+
+          Status = ZwEnumerateKey(ResourceMapKey, 
+                                  ChildKeyIndex1,
+                                  KeyBasicInformation,
+                                  KeyInformation,
+                                  KeyInformationLength,
+                                  &RequiredLength);
+      }
+      else
+         goto cleanup;
+      ChildKeyIndex1++;
+      if (!NT_SUCCESS(Status))
+          goto cleanup;
+
+      KeyName.Buffer = KeyInformation->Name;
+      KeyName.MaximumLength = KeyName.Length = KeyInformation->NameLength;
+      InitializeObjectAttributes(&ObjectAttributes,
+                                 &KeyName,
+                                 OBJ_CASE_INSENSITIVE,
+                                 ResourceMapKey,
+                                 NULL);
+      Status = ZwOpenKey(&ChildKey2, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes);
+      ExFreePool(KeyInformation);
+      if (!NT_SUCCESS(Status))
+          goto cleanup;
+
+      while (TRUE)
+      {
+          Status = ZwEnumerateKey(ChildKey2, 
+                                  ChildKeyIndex2,
+                                  KeyBasicInformation,
+                                  NULL,
+                                  0,
+                                  &RequiredLength);
+          if (Status == STATUS_NO_MORE_ENTRIES)
+              break;
+          else if (Status == STATUS_BUFFER_TOO_SMALL)
+          {
+              KeyInformationLength = RequiredLength;
+              KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength);
+              if (!KeyInformation)
+              {
+                  Status = STATUS_INSUFFICIENT_RESOURCES;
+                  goto cleanup;
+              }
+
+              Status = ZwEnumerateKey(ChildKey2,
+                                      ChildKeyIndex2,
+                                      KeyBasicInformation,
+                                      KeyInformation,
+                                      KeyInformationLength,
+                                      &RequiredLength);
+          }
+          else
+              goto cleanup;
+          ChildKeyIndex2++;
+          if (!NT_SUCCESS(Status))
+              goto cleanup;
+
+          KeyName.Buffer = KeyInformation->Name;
+          KeyName.MaximumLength = KeyName.Length = KeyInformation->NameLength;
+          InitializeObjectAttributes(&ObjectAttributes,
+                                     &KeyName,
+                                     OBJ_CASE_INSENSITIVE,
+                                     ChildKey2,
+                                     NULL);
+          Status = ZwOpenKey(&ChildKey3, KEY_QUERY_VALUE, &ObjectAttributes);
+          ExFreePool(KeyInformation);
+          if (!NT_SUCCESS(Status))
+              goto cleanup;
+
+          while (TRUE)
+          {
+              Status = ZwEnumerateValueKey(ChildKey3,
+                                           ChildKeyIndex3,
+                                           KeyValuePartialInformation,
+                                           NULL,
+                                           0,
+                                           &RequiredLength);
+              if (Status == STATUS_NO_MORE_ENTRIES)
+                  break;
+              else if (Status == STATUS_BUFFER_TOO_SMALL)
+              {
+                  KeyValueInformationLength = RequiredLength;
+                  KeyValueInformation = ExAllocatePool(PagedPool, KeyValueInformationLength);
+                  if (!KeyValueInformation)
+                  {
+                      Status = STATUS_INSUFFICIENT_RESOURCES;
+                      goto cleanup;
+                  }
+
+                  Status = ZwEnumerateValueKey(ChildKey3,
+                                               ChildKeyIndex3,
+                                               KeyValuePartialInformation,
+                                               KeyValueInformation,
+                                               KeyValueInformationLength,
+                                               &RequiredLength);
+              }
+              else
+                  goto cleanup;
+              if (!NT_SUCCESS(Status))
+                  goto cleanup;
+
+              Status = ZwEnumerateValueKey(ChildKey3,
+                                           ChildKeyIndex3,
+                                           KeyValueBasicInformation,
+                                           NULL,
+                                           0,
+                                           &RequiredLength);
+              if (Status == STATUS_BUFFER_TOO_SMALL)
+              {
+                  KeyNameInformationLength = RequiredLength;
+                  KeyNameInformation = ExAllocatePool(PagedPool, KeyNameInformationLength + sizeof(WCHAR));
+                  if (!KeyNameInformation)
+                  {
+                      Status = STATUS_INSUFFICIENT_RESOURCES;
+                      goto cleanup;
+                  }
+
+                  Status = ZwEnumerateValueKey(ChildKey3,
+                                               ChildKeyIndex3,
+                                               KeyValueBasicInformation,
+                                               KeyNameInformation,
+                                               KeyNameInformationLength,
+                                               &RequiredLength);
+              }
+              else
+                  goto cleanup;
+
+              ChildKeyIndex3++;
+
+              if (!NT_SUCCESS(Status))
+                  goto cleanup;
+
+              KeyNameInformation->Name[KeyNameInformation->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
+
+              /* Skip translated entries */
+              if (wcsstr(KeyNameInformation->Name, L".Translated"))
+              {
+                  ExFreePool(KeyNameInformation);
+                  continue;
+              }
+
+              ExFreePool(KeyNameInformation);
+
+              if (IopCheckForResourceConflict(ResourceList,
+                                              (PCM_RESOURCE_LIST)KeyValueInformation->Data,
+                                              Silent,
+                                              ConflictingDescriptor))
+              {
+                  ExFreePool(KeyValueInformation);
+                  Status = STATUS_CONFLICTING_ADDRESSES;
+                  goto cleanup;
+              }
+
+              ExFreePool(KeyValueInformation);
+          }
+      }
+   }
+
+cleanup:
+   if (ResourceMapKey != INVALID_HANDLE_VALUE)
+       ZwClose(ResourceMapKey);
+   if (ChildKey2 != INVALID_HANDLE_VALUE)
+       ZwClose(ChildKey2);
+   if (ChildKey3 != INVALID_HANDLE_VALUE)
+       ZwClose(ChildKey3);
+
+   if (Status == STATUS_NO_MORE_ENTRIES)
+       Status = STATUS_SUCCESS;
+
+   return Status;
+}
+
index a5fa2a0..6f1834e 100644 (file)
@@ -33,7 +33,6 @@ typedef struct _PNPROOT_DEVICE
     UNICODE_STRING DeviceDescription;
     // Resource requirement list
     PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList;
-    ULONG ResourceRequirementsListSize;
     // Associated resource list
     PCM_RESOURCE_LIST ResourceList;
     ULONG ResourceListSize;
@@ -140,29 +139,19 @@ PnpRootCreateDevice(
     WCHAR InstancePath[5];
     PPNPROOT_DEVICE Device = NULL;
     NTSTATUS Status;
-    ULONG i;
     UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\");
+    ULONG NextInstance;
+    UNICODE_STRING EnumKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\" REGSTR_PATH_SYSTEMENUM);
+    HANDLE EnumHandle, DeviceKeyHandle = INVALID_HANDLE_VALUE;
+    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+    OBJECT_ATTRIBUTES ObjectAttributes;
 
     DeviceExtension = PnpRootDeviceObject->DeviceExtension;
     KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
 
     DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName);
 
-    /* Search for a free instance ID */
     _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\%wZ", REGSTR_KEY_ROOTENUM, ServiceName);
-    for (i = 0; i < 9999; i++)
-    {
-        _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", i);
-        Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device);
-        if (Status == STATUS_NO_SUCH_DEVICE)
-            break;
-    }
-    if (i == 9999)
-    {
-        DPRINT1("Too much legacy devices reported for service '%wZ'\n", ServiceName);
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto cleanup;
-    }
 
     /* Initialize a PNPROOT_DEVICE structure */
     Device = ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT);
@@ -178,6 +167,74 @@ PnpRootCreateDevice(
         Status = STATUS_NO_MEMORY;
         goto cleanup;
     }
+
+    Status = IopOpenRegistryKeyEx(&EnumHandle, NULL, &EnumKeyName, KEY_READ);
+    if (NT_SUCCESS(Status))
+    {
+        InitializeObjectAttributes(&ObjectAttributes, &Device->DeviceID, OBJ_CASE_INSENSITIVE, EnumHandle, NULL);
+        Status = ZwCreateKey(&DeviceKeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
+        ZwClose(EnumHandle);
+    }
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open registry key\n");
+        goto cleanup;
+    }
+
+tryagain:
+    RtlZeroMemory(QueryTable, sizeof(QueryTable));
+    QueryTable[0].Name = L"NextInstance";
+    QueryTable[0].EntryContext = &NextInstance;
+    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+
+    Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+                                    (PWSTR)DeviceKeyHandle,
+                                    QueryTable,
+                                    NULL,
+                                    NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        for (NextInstance = 0; NextInstance <= 9999; NextInstance++)
+        {
+             _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
+             Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device);
+             if (Status == STATUS_NO_SUCH_DEVICE)
+                 break;
+        }
+
+        if (NextInstance > 9999)
+        {
+            DPRINT1("Too many legacy devices reported for service '%wZ'\n", ServiceName);
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto cleanup;
+        }
+    }
+
+    _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
+    Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device);
+    if (Status != STATUS_NO_SUCH_DEVICE || NextInstance > 9999)
+    {
+        DPRINT1("NextInstance value is corrupt! (%d)\n", NextInstance);
+        RtlDeleteRegistryValue(RTL_REGISTRY_HANDLE,
+                               (PWSTR)DeviceKeyHandle,
+                               L"NextInstance");
+        goto tryagain;
+    }
+
+    NextInstance++;
+    Status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE,
+                                   (PWSTR)DeviceKeyHandle,
+                                   L"NextInstance",
+                                   REG_DWORD,
+                                   &NextInstance,
+                                   sizeof(NextInstance));
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to write new NextInstance value! (0x%x)\n", Status);
+        goto cleanup;
+    }
+
     if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath))
     {
         Status = STATUS_NO_MEMORY;
@@ -244,6 +301,8 @@ cleanup:
         RtlFreeUnicodeString(&Device->InstanceID);
         ExFreePoolWithTag(Device, TAG_PNP_ROOT);
     }
+    if (DeviceKeyHandle != INVALID_HANDLE_VALUE)
+        ZwClose(DeviceKeyHandle);
     return Status;
 }
 
@@ -677,24 +736,27 @@ PnpRootFdoPnpControl(
                 if (NT_SUCCESS(Status))
                     DeviceExtension->State = dsStarted;
             }
-            break;
+
+            Irp->IoStatus.Status = Status;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return Status;
 
          case IRP_MN_STOP_DEVICE:
              DPRINT("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n");
              /* Root device cannot be stopped */
-             Status = STATUS_NOT_SUPPORTED;
-             break;
+             Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST;
+             IoCompleteRequest(Irp, IO_NO_INCREMENT);
+             return Status;
 
         default:
             DPRINT("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
-            Status = STATUS_NOT_IMPLEMENTED;
             break;
     }
 
     if (Status != STATUS_PENDING)
     {
-        Irp->IoStatus.Status = Status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
     }
 
     return Status;
@@ -707,48 +769,25 @@ PdoQueryDeviceRelations(
     IN PIO_STACK_LOCATION IrpSp)
 {
     PDEVICE_RELATIONS Relations;
-    DEVICE_RELATION_TYPE RelationType;
     NTSTATUS Status = Irp->IoStatus.Status;
 
-    RelationType = IrpSp->Parameters.QueryDeviceRelations.Type;
+    if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
+        return Status;
 
-    switch (RelationType)
+    DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
+    Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
+    if (!Relations)
     {
-        /* FIXME: remove */
-        case BusRelations:
-        {
-            if (IoGetAttachedDevice(DeviceObject) != DeviceObject)
-            {
-                /* We're not alone in the stack */
-                DPRINT1("PnP is misbehaving ; don't know how to handle IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
-            }
-            break;
-        }
-
-        case TargetDeviceRelation:
-        {
-            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
-            Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
-            if (!Relations)
-            {
-                DPRINT("ExAllocatePoolWithTag() failed\n");
-                Status = STATUS_NO_MEMORY;
-            }
-            else
-            {
-                ObReferenceObject(DeviceObject);
-                Relations->Count = 1;
-                Relations->Objects[0] = DeviceObject;
-                Status = STATUS_SUCCESS;
-                Irp->IoStatus.Information = (ULONG_PTR)Relations;
-            }
-            break;
-        }
-
-        default:
-        {
-            DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / unknown relation type 0x%lx\n", RelationType);
-        }
+        DPRINT("ExAllocatePoolWithTag() failed\n");
+        Status = STATUS_NO_MEMORY;
+    }
+    else
+    {
+        ObReferenceObject(DeviceObject);
+        Relations->Count = 1;
+        Relations->Objects[0] = DeviceObject;
+        Status = STATUS_SUCCESS;
+        Irp->IoStatus.Information = (ULONG_PTR)Relations;
     }
 
     return Status;
@@ -786,35 +825,29 @@ PdoQueryResources(
 
     DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-    if (DeviceExtension->DeviceInfo->ResourceList == NULL)
-    {
-        /* Create an empty resource list */
-        ResourceList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST));
-        if (!ResourceList)
-            return STATUS_NO_MEMORY;
-
-        ResourceList->Count = 0;
-
-        Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
-    }
-    else
+    if (DeviceExtension->DeviceInfo->ResourceList)
     {
         /* Copy existing resource requirement list */
         ResourceList = ExAllocatePool(
             PagedPool,
-            FIELD_OFFSET(CM_RESOURCE_LIST, List) + DeviceExtension->DeviceInfo->ResourceListSize);
+            DeviceExtension->DeviceInfo->ResourceListSize);
         if (!ResourceList)
             return STATUS_NO_MEMORY;
 
-        ResourceList->Count = 1;
         RtlCopyMemory(
-            &ResourceList->List,
+            ResourceList,
             DeviceExtension->DeviceInfo->ResourceList,
             DeviceExtension->DeviceInfo->ResourceListSize);
-            Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
-    }
 
-    return STATUS_SUCCESS;
+        Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+
+        return STATUS_SUCCESS;
+    }
+    else
+    {
+        /* No resources so just return without changing the status */
+        return Irp->IoStatus.Status;
+    }
 }
 
 static NTSTATUS
@@ -825,23 +858,10 @@ PdoQueryResourceRequirements(
 {
     PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
     PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
-    ULONG ResourceListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List);
 
     DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-    if (DeviceExtension->DeviceInfo->ResourceRequirementsList == NULL)
-    {
-        /* Create an empty resource list */
-        ResourceList = ExAllocatePool(PagedPool, ResourceListSize);
-        if (!ResourceList)
-            return STATUS_NO_MEMORY;
-
-        RtlZeroMemory(ResourceList, ResourceListSize);
-        ResourceList->ListSize = ResourceListSize;
-
-        Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
-    }
-    else
+    if (DeviceExtension->DeviceInfo->ResourceRequirementsList)
     {
         /* Copy existing resource requirement list */
         ResourceList = ExAllocatePool(PagedPool, DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
@@ -852,10 +872,16 @@ PdoQueryResourceRequirements(
             ResourceList,
             DeviceExtension->DeviceInfo->ResourceRequirementsList,
             DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
-            Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
-    }
 
-    return STATUS_SUCCESS;
+        Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+
+        return STATUS_SUCCESS;
+    }
+    else
+    {
+        /* No resource requirements so just return without changing the status */
+        return Irp->IoStatus.Status;
+    }
 }
 
 static NTSTATUS
@@ -1043,6 +1069,11 @@ PnpRootPdoPnpControl(
         DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
         break;
 
+    case IRP_MN_REMOVE_DEVICE:
+        DPRINT1("IRP_MN_REMOVE_DEVICE is UNIMPLEMENTED!\n");
+        Status = STATUS_SUCCESS;
+        break;
+
     case IRP_MN_QUERY_ID: /* 0x13 */
       Status = PdoQueryId(DeviceObject, Irp, IrpSp);
       break;
@@ -1159,6 +1190,8 @@ PnpRootDriverEntry(
 {
     DPRINT("PnpRootDriverEntry(%p %wZ)\n", DriverObject, RegistryPath);
 
+    IopRootDriverObject = DriverObject;
+    
     DriverObject->DriverExtension->AddDevice = PnpRootAddDevice;
 
     DriverObject->MajorFunction[IRP_MJ_PNP] = PnpRootPnpControl;
diff --git a/ntoskrnl/io/pnpmgr/pnputil.c b/ntoskrnl/io/pnpmgr/pnputil.c
new file mode 100644 (file)
index 0000000..f274f3d
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            ntoskrnl/io/pnpmgr/pnputil.c
+ * PURPOSE:         PnP Utility Code
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+PnpFreeUnicodeStringList(IN PUNICODE_STRING UnicodeStringList,
+                         IN ULONG StringCount)
+{
+    ULONG i;
+    
+    /* Go through the list */
+    if (UnicodeStringList)
+    {
+        /* Go through each string */
+        for (i = 0; i < StringCount; i++)
+        {
+            /* Check if it exists */
+            if (UnicodeStringList[i].Buffer)
+            {
+                /* Free it */
+                ExFreePool(UnicodeStringList[i].Buffer);
+            }
+        }
+        
+        /* Free the whole list */
+        ExFreePool(UnicodeStringList);
+    }
+}
+
+NTSTATUS
+NTAPI
+PnpRegMultiSzToUnicodeStrings(IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation,
+                              OUT PUNICODE_STRING *UnicodeStringList,
+                              OUT PULONG UnicodeStringCount)
+{
+    PWCHAR p, pp, ps;
+    ULONG i = 0, n;
+    ULONG Count = 0;
+    
+    /* Validate the key information */
+    if (KeyValueInformation->Type != REG_MULTI_SZ) return STATUS_INVALID_PARAMETER;
+    
+    /* Set the pointers */
+    p = (PWCHAR)((ULONG_PTR)KeyValueInformation +
+                 KeyValueInformation->DataOffset);
+    pp = (PWCHAR)((ULONG_PTR)p + KeyValueInformation->DataLength);
+    
+    /* Loop the data */
+    while (p != pp)
+    {
+        /* If we find a NULL, that means one string is done */
+        if (!*p)
+        {
+            /* Add to our string count */
+            Count++;
+            
+            /* Check for a double-NULL, which means we're done */
+            if (((p + 1) == pp) || !(*(p + 1))) break;
+        }
+    
+        /* Go to the next character */
+        p++;
+    }
+
+    /* If we looped the whole list over, we missed increment a string, do it */
+    if (p == pp) Count++;
+    
+    /* Allocate the list now that we know how big it is */
+    *UnicodeStringList = ExAllocatePoolWithTag(PagedPool,
+                                               sizeof(UNICODE_STRING) * Count,
+                                               'sUpP');
+    if (!(*UnicodeStringList)) return STATUS_INSUFFICIENT_RESOURCES;
+    
+    /* Set pointers for second loop */
+    ps = p = (PWCHAR)((ULONG_PTR)KeyValueInformation +
+                     KeyValueInformation->DataOffset);
+    
+    /* Loop again, to do the copy this time */
+    while (p != pp)
+    {
+        /* If we find a NULL, that means one string is done */
+        if (!*p)
+        {
+            /* Check how long this string is */
+            n = (ULONG_PTR)p - (ULONG_PTR)ps + sizeof(UNICODE_NULL);
+            
+            /* Allocate the buffer */
+            (*UnicodeStringList)[i].Buffer = ExAllocatePoolWithTag(PagedPool,
+                                                                   n,
+                                                                   'sUpP');
+            if (!(*UnicodeStringList)[i].Buffer)
+            {
+                /* Back out of everything */
+                PnpFreeUnicodeStringList(*UnicodeStringList, i);
+                return STATUS_INSUFFICIENT_RESOURCES;
+            }
+            
+            /* Copy the string into the buffer */
+            RtlCopyMemory((*UnicodeStringList)[i].Buffer, ps, n);
+            
+            /* Set the lengths */
+            (*UnicodeStringList)[i].MaximumLength = n;
+            (*UnicodeStringList)[i].Length = n - sizeof(UNICODE_NULL);
+            
+            /* One more entry done */
+            i++;
+            
+            /* Check for a double-NULL, which means we're done */
+            if (((p + 1) == pp) || !(*(p + 1))) break;
+
+            /* New string */
+            ps = p + 1;
+        }
+        
+        /* New string */
+        p++;
+    }
+    
+    /* Check if we've reached the last string */
+    if (p == pp)
+    {
+        /* Calculate the string length */
+        n = (ULONG_PTR)p - (ULONG_PTR)ps;
+        
+        /* Allocate the buffer for it */
+        (*UnicodeStringList)[i].Buffer = ExAllocatePoolWithTag(PagedPool,
+                                                               n +
+                                                               sizeof(UNICODE_NULL),
+                                                               'sUpP');
+        if (!(*UnicodeStringList)[i].Buffer)
+        {
+            /* Back out of everything */
+            PnpFreeUnicodeStringList(*UnicodeStringList, i);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+        
+        /* Make sure there's an actual string here */
+        if (n) RtlCopyMemory((*UnicodeStringList)[i].Buffer, ps, n);
+
+        /* Null-terminate the string ourselves */
+        (*UnicodeStringList)[i].Buffer[n / sizeof(WCHAR)] = UNICODE_NULL;
+        
+        /* Set the lenghts */
+        (*UnicodeStringList)[i].Length = n;
+        (*UnicodeStringList)[i].MaximumLength = n + sizeof(UNICODE_NULL);
+    }
+    
+    /* And we're done */
+    *UnicodeStringCount = Count;
+    return STATUS_SUCCESS;
+}
+
+BOOLEAN
+NTAPI
+PnpRegSzToString(IN PWCHAR RegSzData,
+                 IN ULONG RegSzLength,
+                 OUT PUSHORT StringLength OPTIONAL)
+{
+    PWCHAR p, pp;
+    
+    /* Find the end */
+    pp = RegSzData + RegSzLength;
+    for (p = RegSzData; p < pp; p++) if (!*p) break;
+    
+    /* Return it */
+    if (StringLength) *StringLength = p - RegSzData;
+    return TRUE;
+}
+
+/* EOF */
index fa42826..4c469fd 100644 (file)
@@ -823,7 +823,8 @@ KdbpCmdBackTrace(
             break;
         }
 
-        if (!KdbSymPrintAddress((PVOID)Address))
+        /* Print the location of the call instruction */
+        if (!KdbSymPrintAddress((PVOID)(Address - 5)))
             KdbpPrint("<%08x>\n", Address);
         else
             KdbpPrint("\n");
index 284ff19..38dded7 100644 (file)
@@ -584,7 +584,7 @@ KeContextToTrapFrame(IN PCONTEXT Context,
     }
 
     /* Handle the Debug Registers */
-    if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
+    if (0 && (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
     {
         /* Loop DR registers */
         for (i = 0; i < 4; i++)
index f9a954e..b9033c2 100644 (file)
@@ -240,7 +240,7 @@ KiNpxHandler(IN PKTRAP_FRAME TrapFrame,
     }
 
     /* User or kernel trap -- get ready to issue an exception */
-    if (Thread->NpxState == NPX_STATE_NOT_LOADED)
+    //if (Thread->NpxState == NPX_STATE_NOT_LOADED)
     {
         /* Update CR0 */
         Cr0 = __readcr0();
@@ -248,7 +248,7 @@ KiNpxHandler(IN PKTRAP_FRAME TrapFrame,
         __writecr0(Cr0);
 
         /* Save FPU state */
-        //Ke386SaveFpuState(SaveArea);
+        Ke386SaveFpuState(SaveArea);
 
         /* Mark CR0 state dirty */
         Cr0 |= NPX_STATE_NOT_LOADED;
@@ -1082,64 +1082,64 @@ KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
      * we should probably table this for now since it's not a "real" issue.
      */
      
-     /*
-      * NOTE2: Another scenario is the IRET during a V8086 restore (BIOS Call)
-      * which will cause a GPF since the trap frame is a total mess (on purpose)
-      * as built in KiEnterV86Mode.
-      *
-      * The idea is to scan for IRET, scan for the known EIP adress, validate CS
-      * and then manually issue a jump to the V8086 return EIP.
-      */
-     Instructions = (PUCHAR)TrapFrame->Eip;
-     if (Instructions[0] == 0xCF)
-     {
-         /*
-          * Some evil shit is going on here -- this is not the SS:ESP you're 
-          * looking for! Instead, this is actually CS:EIP you're looking at!
-          * Why? Because part of the trap frame actually corresponds to the IRET
-          * stack during the trap exit!
-          */
-          if ((TrapFrame->HardwareEsp == (ULONG)Ki386BiosCallReturnAddress) &&
-              (TrapFrame->HardwareSegSs == (KGDT_R0_CODE | RPL_MASK)))
-          {
-              /* Exit the V86 trap! */
-              Ki386BiosCallReturnAddress(TrapFrame);
-          }
-          else
-          {
-              /* Otherwise, this is another kind of IRET fault */
-              UNIMPLEMENTED;
-              while (TRUE);
-          }
-     }
+    /*
+     * NOTE2: Another scenario is the IRET during a V8086 restore (BIOS Call)
+     * which will cause a GPF since the trap frame is a total mess (on purpose)
+     * as built in KiEnterV86Mode.
+     *
+     * The idea is to scan for IRET, scan for the known EIP adress, validate CS
+     * and then manually issue a jump to the V8086 return EIP.
+     */
+    Instructions = (PUCHAR)TrapFrame->Eip;
+    if (Instructions[0] == 0xCF)
+    {
+        /*
+         * Some evil shit is going on here -- this is not the SS:ESP you're 
+         * looking for! Instead, this is actually CS:EIP you're looking at!
+         * Why? Because part of the trap frame actually corresponds to the IRET
+         * stack during the trap exit!
+         */
+        if ((TrapFrame->HardwareEsp == (ULONG)Ki386BiosCallReturnAddress) &&
+            (TrapFrame->HardwareSegSs == (KGDT_R0_CODE | RPL_MASK)))
+        {
+            /* Exit the V86 trap! */
+            Ki386BiosCallReturnAddress(TrapFrame);
+        }
+        else
+        {
+            /* Otherwise, this is another kind of IRET fault */
+            UNIMPLEMENTED;
+            while (TRUE);
+        }
+    }
      
      /* So since we're not dealing with the above case, check for RDMSR/WRMSR */
-     if ((Instructions[0] == 0xF) &&            // 2-byte opcode
+    if ((Instructions[0] == 0xF) &&            // 2-byte opcode
         (((Instructions[1] >> 8) == 0x30) ||        // RDMSR
          ((Instructions[2] >> 8) == 0x32)))         // WRMSR
-     {
+    {
         /* Unknown CPU MSR, so raise an access violation */
         KiDispatchException0Args(STATUS_ACCESS_VIOLATION,
                                  TrapFrame->Eip,
                                  TrapFrame);
-     }
-
-     /* Check for lazy segment load */
-     if (TrapFrame->SegDs != (KGDT_R3_DATA | RPL_MASK))
-     {
-         /* Fix it */
-         TrapFrame->SegDs = (KGDT_R3_DATA | RPL_MASK);
-     }
-     else if (TrapFrame->SegEs != (KGDT_R3_DATA | RPL_MASK))
-     {
+    }
+
+    /* Check for lazy segment load */
+    if (TrapFrame->SegDs != (KGDT_R3_DATA | RPL_MASK))
+    {
+        /* Fix it */
+        TrapFrame->SegDs = (KGDT_R3_DATA | RPL_MASK);
+    }
+    else if (TrapFrame->SegEs != (KGDT_R3_DATA | RPL_MASK))
+    {
         /* Fix it */
         TrapFrame->SegEs = (KGDT_R3_DATA | RPL_MASK);
-     }
-     else
-     {
-         /* Whatever it is, we can't handle it */
-         KiSystemFatalException(EXCEPTION_GP_FAULT, TrapFrame);
-     }
+    }
+    else
+    {
+        /* Whatever it is, we can't handle it */
+        KiSystemFatalException(EXCEPTION_GP_FAULT, TrapFrame);
+    }
     
     /* Return to where we came from */
     KiTrapReturn(TrapFrame);
@@ -1353,7 +1353,7 @@ KiTrap13Handler(IN PKTRAP_FRAME TrapFrame)
     __writecr0(Cr0);
     
     /* Save FPU state */
-    //Ke386SaveFpuState(SaveArea);
+    Ke386SaveFpuState(SaveArea);
     
     /* Mark CR0 state dirty */
     Cr0 |= NPX_STATE_NOT_LOADED;
@@ -1379,7 +1379,7 @@ KiTrap13Handler(IN PKTRAP_FRAME TrapFrame)
                                                 FSW_UNDERFLOW |
                                                 FSW_PRECISION);
     Error &= MxCsrMask;
-    
+
     /* Now handle any of those legal errors */
     if (Error & (FSW_INVALID_OPERATION |
                  FSW_DENORMAL |
index 4811a44..ad85c47 100644 (file)
 MM_DRIVER_VERIFIER_DATA MmVerifierData;
 LIST_ENTRY MiVerifierDriverAddedThunkListHead;
 ULONG MiActiveVerifierThunks;
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-PLDR_DATA_TABLE_ENTRY
-NTAPI
-MiLookupDataTableEntry(IN PVOID Address)
-{
-    PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
-    PLIST_ENTRY NextEntry;
-    PAGED_CODE();
-    
-    //
-    // Loop entries
-    //
-    NextEntry = PsLoadedModuleList.Flink;
-    do
-    {
-        //
-        // Get the loader entry
-        //
-        LdrEntry =  CONTAINING_RECORD(NextEntry,
-                                      LDR_DATA_TABLE_ENTRY,
-                                      InLoadOrderLinks);
-        
-        //
-        // Check if the address matches
-        //
-        if ((Address >= LdrEntry->DllBase) &&
-            (Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase +
-                               LdrEntry->SizeOfImage)))
-        {
-            //
-            // Found a match
-            //
-            FoundEntry = LdrEntry;
-            break;
-        }
-        
-        //
-        // Move on
-        //
-        NextEntry = NextEntry->Flink;
-    } while(NextEntry != &PsLoadedModuleList);
-    
-    //
-    // Return the entry
-    //
-    return FoundEntry;
-}
+WCHAR MmVerifyDriverBuffer[512] = {0};
+ULONG MmVerifyDriverBufferLength = sizeof(MmVerifyDriverBuffer);
+ULONG MmVerifyDriverBufferType = REG_NONE;
+ULONG MmVerifyDriverLevel = -1;
+PVOID MmTriageActionTaken;
+PVOID KernelVerifier;
 
 /* PUBLIC FUNCTIONS ***********************************************************/
 
@@ -107,68 +64,6 @@ MmLockPageableDataSection(IN PVOID AddressWithinSection)
     return AddressWithinSection;
 }
 
-/*
- * @unimplemented
- */
-PVOID
-NTAPI
-MmPageEntireDriver(IN PVOID AddressWithinSection)
-{
-    //PMMPTE StartPte, EndPte;
-    PLDR_DATA_TABLE_ENTRY LdrEntry;
-    PAGED_CODE();
-
-    //
-    // Get the loader entry
-    //
-    LdrEntry = MiLookupDataTableEntry(AddressWithinSection);
-    if (!LdrEntry) return NULL;
-
-    //
-    // Check if paging of kernel mode is disabled or if the driver is mapped as
-    // an image
-    //
-    if ((MmDisablePagingExecutive & 0x1) || (LdrEntry->SectionPointer))
-    {
-        //
-        // Don't do anything, just return the base address
-        //
-        return LdrEntry->DllBase;
-    }
-
-    //
-    // Wait for active DPCs to finish before we page out the driver
-    //
-    KeFlushQueuedDpcs();
-
-    //
-    // Get the PTE range for the whole driver image
-    //
-    //StartPte = MiGetPteAddress(LdrEntry->DllBase);
-    //EndPte = MiGetPteAddress(LdrEntry->DllBase +
-    //                         LdrEntry->SizeOfImage);
-
-    //
-    // Enable paging for the PTE range
-    //
-    //MiSetPagingOfDriver(StartPte, EndPte);
-
-    //
-    // Return the base address
-    //
-    return LdrEntry->DllBase;
-}
-
-/*
- * @unimplemented
- */
-VOID
-NTAPI
-MmResetDriverPaging(IN PVOID AddressWithinSection)
-{
-    UNIMPLEMENTED;
-}
-
 /*
  * @unimplemented
  */
diff --git a/ntoskrnl/mm/ARM3/largepag.c b/ntoskrnl/mm/ARM3/largepag.c
new file mode 100644 (file)
index 0000000..0cd1e50
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            ntoskrnl/mm/ARM3/largepag.c
+ * PURPOSE:         ARM Memory Manager Large Page Support
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+#line 15 "ARM³::LARGEPAGE"
+#define MODULE_INVOLVED_IN_ARM3
+#include "../ARM3/miarm.h"
+
+/* GLOBALS ********************************************************************/
+
+LIST_ENTRY MmProcessList;
+PMMPTE MiLargePageHyperPte;
+ULONG MiLargePageRangeIndex;
+MI_LARGE_PAGE_RANGES MiLargePageRanges[64];
+WCHAR MmLargePageDriverBuffer[512] = {0};
+ULONG MmLargePageDriverBufferLength = -1;
+LIST_ENTRY MiLargePageDriverList;
+BOOLEAN MiLargePageAllDrivers;
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+MiInitializeLargePageSupport(VOID)
+{
+#if _MI_PAGING_LEVELS > 2
+#error "PAE/x64 Not Implemented"
+#else
+    /* Initialize the large-page hyperspace PTE used for initial mapping */
+    MiLargePageHyperPte = MiReserveSystemPtes(1, SystemPteSpace);
+    ASSERT(MiLargePageHyperPte);
+    MiLargePageHyperPte->u.Long = 0;
+
+    /* Initialize the process tracking list, and insert the system process */
+    InitializeListHead(&MmProcessList);
+    InsertTailList(&MmProcessList, &PsGetCurrentProcess()->MmProcessLinks);
+#endif    
+}
+
+VOID
+NTAPI
+MiSyncCachedRanges(VOID)
+{
+    ULONG i;
+
+    /* Scan every range */
+    for (i = 0; i < MiLargePageRangeIndex; i++)
+    {
+        DPRINT1("No support for large pages\n");
+        while (TRUE);
+    }
+}
+
+VOID
+NTAPI
+MiInitializeDriverLargePageList(VOID)
+{
+    PWCHAR p, pp;
+
+    /* Initialize the list */
+    InitializeListHead(&MiLargePageDriverList);
+
+    /* Bail out if there's nothing */
+    if (MmLargePageDriverBufferLength == 0xFFFFFFFF) return;
+
+    /* Loop from start to finish */
+    p = MmLargePageDriverBuffer;
+    pp = MmLargePageDriverBuffer + (MmLargePageDriverBufferLength / sizeof(WCHAR));
+    while (p < pp)
+    {
+        /* Skip whitespaces */
+        if ((*p == L' ') || (*p == L'\n') || (*p == L'\r') || (*p == L'\t'))
+        {
+            /* Skip the character */
+            p++;
+            continue;
+        }
+        
+        /* A star means everything */
+        if (*p == L'*')
+        {
+            /* No need to keep going */
+            MiLargePageAllDrivers = TRUE;
+            break;
+        }
+        
+        DPRINT1("Large page drivers not supported\n");
+        ASSERT(FALSE);
+    }
+}
+
+/* EOF */
index 0100040..1b95448 100644 (file)
@@ -16,6 +16,9 @@
 #define MODULE_INVOLVED_IN_ARM3
 #include "../ARM3/miarm.h"
 
+BOOLEAN MmTrackPtes;
+BOOLEAN MmTrackLockedPages;
+
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 /*
index 389781c..11d4189 100644 (file)
 
 /* Make the code cleaner with some definitions for size multiples */
 #define _1KB (1024)
-#define _1MB (1000 * _1KB)
+#define _1MB (1024 * _1KB)
+
+/* Are mapped by a PDE */
+#define PDE_MAPPED_VA   (PTE_COUNT * PAGE_SIZE)
 
 /* Size of a PDE directory, and size of a page table */
 #define PDE_SIZE (PDE_COUNT * sizeof(MMPDE))
 #error Define these please!
 #endif
 
+#ifdef _M_IX86
+#define IMAGE_FILE_MACHINE_NATIVE   IMAGE_FILE_MACHINE_I386
+#elif _M_ARM
+#define IMAGE_FILE_MACHINE_NATIVE   IMAGE_FILE_MACHINE_ARM
+#elif _M_AMD64
+#define IMAGE_FILE_MACHINE_NATIVE   IMAGE_FILE_MACHINE_AMD64
+#else
+#error Define these please!
+#endif
+
+//
+// Protection Bits part of the internal memory manager Protection Mask
+// Taken from http://www.reactos.org/wiki/Techwiki:Memory_management_in_the_Windows_XP_kernel
+// and public assertions.
+//
+#define MM_ZERO_ACCESS         0
+#define MM_READONLY            1 
+#define MM_EXECUTE             2 
+#define MM_EXECUTE_READ        3 
+#define MM_READWRITE           4
+#define MM_WRITECOPY           5 
+#define MM_EXECUTE_READWRITE   6 
+#define MM_EXECUTE_WRITECOPY   7 
+#define MM_NOCACHE             8 
+#define MM_DECOMMIT            0x10 
+#define MM_NOACCESS            (MM_DECOMMIT | MM_NOCACHE)
+
+//
+// Special values for LoadedImports
+//
+#define MM_SYSLDR_NO_IMPORTS   (PVOID)0xFFFFFFFE
+#define MM_SYSLDR_BOOT_LOADED  (PVOID)0xFFFFFFFF
+#define MM_SYSLDR_SINGLE_ENTRY 0x1
+
 //
 // PFN List Sentinel
 //
@@ -127,6 +164,12 @@ extern PVOID PoolTrackTable;
 // END FIXFIX
 //
 
+typedef struct _MI_LARGE_PAGE_DRIVER_ENTRY
+{
+    LIST_ENTRY Links;
+    UNICODE_STRING BaseName;
+} MI_LARGE_PAGE_DRIVER_ENTRY, *PMI_LARGE_PAGE_DRIVER_ENTRY;
+
 typedef enum _MMSYSTEM_PTE_POOL_TYPE
 {
     SystemPteSpace,
@@ -162,10 +205,34 @@ typedef struct _MMCOLOR_TABLES
     PFN_NUMBER Count;
 } MMCOLOR_TABLES, *PMMCOLOR_TABLES;
 
+typedef struct _MI_LARGE_PAGE_RANGES
+{
+    PFN_NUMBER StartFrame;
+    PFN_NUMBER LastFrame;
+} MI_LARGE_PAGE_RANGES, *PMI_LARGE_PAGE_RANGES;
+
 extern MMPTE HyperTemplatePte;
 extern MMPTE ValidKernelPde;
 extern MMPTE ValidKernelPte;
-
+extern BOOLEAN MmLargeSystemCache;
+extern BOOLEAN MmZeroPageFile;
+extern BOOLEAN MmProtectFreedNonPagedPool;
+extern BOOLEAN MmTrackLockedPages;
+extern BOOLEAN MmTrackPtes;
+extern BOOLEAN MmDynamicPfn;
+extern BOOLEAN MmMirroring;
+extern BOOLEAN MmMakeLowMemory;
+extern BOOLEAN MmEnforceWriteProtection;
+extern ULONG MmAllocationFragment;
+extern ULONG MmConsumedPoolPercentage;
+extern ULONG MmVerifyDriverBufferType;
+extern ULONG MmVerifyDriverLevel;
+extern WCHAR MmVerifyDriverBuffer[512];
+extern WCHAR MmLargePageDriverBuffer[512];
+extern LIST_ENTRY MiLargePageDriverList;
+extern BOOLEAN MiLargePageAllDrivers;
+extern ULONG MmVerifyDriverBufferLength;
+extern ULONG MmLargePageDriverBufferLength;
 extern ULONG MmSizeOfNonPagedPoolInBytes;
 extern ULONG MmMaximumNonPagedPoolInBytes;
 extern PFN_NUMBER MmMaximumNonPagedPoolInPages;
@@ -235,10 +302,34 @@ extern PFN_NUMBER MiLowNonPagedPoolThreshold;
 extern PFN_NUMBER MiHighNonPagedPoolThreshold;
 extern PFN_NUMBER MmMinimumFreePages;
 extern PFN_NUMBER MmPlentyFreePages;
+extern PFN_NUMBER MiExpansionPoolPagesInitialCharge;
+extern PFN_NUMBER MmResidentAvailablePages;
+extern PFN_NUMBER MmResidentAvailableAtInit;
+extern ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes];
+extern PFN_NUMBER MmTotalSystemDriverPages;
+extern PVOID MiSessionImageStart;
+extern PVOID MiSessionImageEnd;
 
 #define MI_PFN_TO_PFNENTRY(x)     (&MmPfnDatabase[1][x])
 #define MI_PFNENTRY_TO_PFN(x)     (x - MmPfnDatabase[1])
 
+#define MI_IS_SESSION_IMAGE_ADDRESS(Address) \
+    (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd))
+
+#define MI_IS_SESSION_ADDRESS(Address) \
+    (((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd))
+        
+FORCEINLINE
+BOOLEAN
+MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
+{
+    PMMPDE PointerPde;
+    
+    /* Large pages are never paged out, always physically resident */
+    PointerPde = MiAddressToPde(Address);
+    return ((PointerPde->u.Hard.LargePage) && (PointerPde->u.Hard.Valid));
+}
+
 NTSTATUS
 NTAPI
 MmArmInitSystem(
@@ -448,4 +539,28 @@ MiInsertPageInFreeList(
     IN PFN_NUMBER PageFrameIndex
 );
 
+PLDR_DATA_TABLE_ENTRY
+NTAPI
+MiLookupDataTableEntry(
+    IN PVOID Address
+);
+
+VOID
+NTAPI
+MiInitializeDriverLargePageList(
+    VOID
+);
+
+VOID
+NTAPI
+MiInitializeLargePageSupport(
+    VOID
+);
+
+VOID
+NTAPI
+MiSyncCachedRanges(
+    VOID
+);
+
 /* EOF */
index 89d082e..d21adc0 100644 (file)
@@ -301,6 +301,20 @@ PFN_NUMBER MmPlentyFreePages = 400;
 ULONG MmProductType;
 MM_SYSTEMSIZE MmSystemSize;
 
+/*
+ * These values store the cache working set minimums and maximums, in pages
+ *
+ * The minimum value is boosted on systems with more than 24MB of RAM, and cut
+ * down to only 32 pages on embedded (<24MB RAM) systems.
+ *
+ * An extra boost of 2MB is given on systems with more than 33MB of RAM.
+ */
+PFN_NUMBER MmSystemCacheWsMinimum = 288;
+PFN_NUMBER MmSystemCacheWsMaximum = 350;
+
+/* FIXME: Move to cache/working set code later */
+BOOLEAN MmLargeSystemCache;
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 //
@@ -742,7 +756,7 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
         else
         {
             /* Next PDE mapped address */
-            BaseAddress += PTE_COUNT * PAGE_SIZE;
+            BaseAddress += PDE_MAPPED_VA;
         }
         
         /* Next PTE */
@@ -1159,6 +1173,61 @@ MiInitializeMemoryEvents(VOID)
     return TRUE;
 }
 
+VOID
+NTAPI
+MiAddHalIoMappings(VOID)
+{
+    PVOID BaseAddress;
+    PMMPTE PointerPde;
+    PMMPTE PointerPte;
+    ULONG i, j, PdeCount;
+    PFN_NUMBER PageFrameIndex;
+
+    /* HAL Heap address -- should be on a PDE boundary */
+    BaseAddress = (PVOID)0xFFC00000;
+    ASSERT(MiAddressToPteOffset(BaseAddress) == 0);
+
+    /* Check how many PDEs the heap has */
+    PointerPde = MiAddressToPde(BaseAddress);
+    PdeCount = PDE_COUNT - ADDR_TO_PDE_OFFSET(BaseAddress);
+    for (i = 0; i < PdeCount; i++)
+    {
+        /* Does the HAL own this mapping? */
+        if ((PointerPde->u.Hard.Valid == 1) &&
+            (PointerPde->u.Hard.LargePage == 0))
+        {
+            /* Get the PTE for it and scan each page */
+            PointerPte = MiAddressToPte(BaseAddress);
+            for (j = 0 ; j < PTE_COUNT; j++)
+            {
+                /* Does the HAL own this page? */
+                if (PointerPte->u.Hard.Valid == 1)
+                {
+                    /* Is the HAL using it for device or I/O mapped memory? */
+                    PageFrameIndex = PFN_FROM_PTE(PointerPte);
+                    if (!MiGetPfnEntry(PageFrameIndex))
+                    {
+                        /* FIXME: For PAT, we need to track I/O cache attributes for coherency */
+                        DPRINT1("HAL I/O Mapping at %p is unsafe\n", BaseAddress);
+                    }
+                }
+
+                /* Move to the next page */
+                BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_SIZE);
+                PointerPte++;
+            }
+        }
+        else
+        {
+            /* Move to the next address */
+            BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + PDE_MAPPED_VA);
+        }
+
+        /* Move to the next PDE */
+        PointerPde++;
+    }
+}
+
 VOID
 NTAPI
 MmDumpArmPfnDatabase(VOID)
@@ -1813,11 +1882,26 @@ MmArmInitSystem(IN ULONG Phase,
             }
         }
         
-        //
-        // Size up paged pool and build the shadow system page directory
-        //
-        MiBuildPagedPool();
-        
+        /* Look for large page cache entries that need caching */
+        MiSyncCachedRanges();
+
+        /* Loop for HAL Heap I/O device mappings that need coherency tracking */
+        MiAddHalIoMappings();
+
+        /* Set the initial resident page count */
+        MmResidentAvailablePages = MmAvailablePages - 32;
+
+        /* Initialize large page structures on PAE/x64, and MmProcessList on x86 */
+        MiInitializeLargePageSupport();
+
+        /* Check if the registry says any drivers should be loaded with large pages */
+        MiInitializeDriverLargePageList();
+
+        /* Relocate the boot drivers into system PTE space and fixup their PFNs */
+        MiReloadBootLoadedDrivers(LoaderBlock);
+
+        /* FIXME: Call out into Driver Verifier for initialization  */
+
         /* Check how many pages the system has */
         if (MmNumberOfPhysicalPages <= (13 * _1MB))
         {
@@ -1826,13 +1910,22 @@ MmArmInitSystem(IN ULONG Phase,
         }
         else if (MmNumberOfPhysicalPages <= (19 * _1MB))
         {
-            /* Set small system */
+            /* Set small system and add 100 pages for the cache */
             MmSystemSize = MmSmallSystem;
+            MmSystemCacheWsMinimum += 100;
         }
         else
         {
-            /* Set medium system */
+            /* Set medium system and add 400 pages for the cache */
             MmSystemSize = MmMediumSystem;
+            MmSystemCacheWsMinimum += 400;
+        }
+        
+        /* Check for less than 24MB */
+        if (MmNumberOfPhysicalPages < ((24 * _1MB) / PAGE_SIZE))
+        {
+            /* No more than 32 pages */
+            MmSystemCacheWsMinimum = 32;
         }
 
         /* Check for more than 32MB */
@@ -1854,7 +1947,14 @@ MmArmInitSystem(IN ULONG Phase,
                 }
             }
         }
-
+        
+        /* Check for more than 33 MB */
+        if (MmNumberOfPhysicalPages > ((33 * _1MB) / PAGE_SIZE))
+        {
+            /* Add another 500 pages to the cache */
+            MmSystemCacheWsMinimum += 500;
+        }
+        
         /* Now setup the shared user data fields */
         ASSERT(SharedUserData->NumberOfPhysicalPages == 0);
         SharedUserData->NumberOfPhysicalPages = MmNumberOfPhysicalPages;
@@ -1888,6 +1988,20 @@ MmArmInitSystem(IN ULONG Phase,
 
         /* Update working set tuning parameters */
         MiAdjustWorkingSetManagerParameters(!MmProductType);
+
+        /* Finetune the page count by removing working set and NP expansion */
+        MmResidentAvailablePages -= MiExpansionPoolPagesInitialCharge;
+        MmResidentAvailablePages -= MmSystemCacheWsMinimum;
+        MmResidentAvailableAtInit = MmResidentAvailablePages;
+        if (MmResidentAvailablePages <= 0)
+        {
+            /* This should not happen */
+            DPRINT1("System cache working set too big\n");
+            return FALSE;
+        }
+        
+        /* Size up paged pool and build the shadow system page directory */
+        MiBuildPagedPool();
     }
     
     //
index 5804340..f42abdc 100644 (file)
@@ -18,6 +18,9 @@
 
 /* GLOBALS ********************************************************************/
 
+BOOLEAN MmDynamicPfn;
+BOOLEAN MmMirroring;
+
 MMPFNLIST MmZeroedPageListHead = {0, ZeroedPageList, LIST_HEAD, LIST_HEAD};
 MMPFNLIST MmFreePageListHead = {0, FreePageList, LIST_HEAD, LIST_HEAD};
 MMPFNLIST MmStandbyPageListHead = {0, StandbyPageList, LIST_HEAD, LIST_HEAD};
index bd2f826..10a585e 100644 (file)
@@ -26,6 +26,8 @@ KGUARDED_MUTEX MmPagedPoolMutex;
 MM_PAGED_POOL_INFO MmPagedPoolInfo;
 SIZE_T MmAllocatedNonPagedPool;
 ULONG MmSpecialPoolTag;
+ULONG MmConsumedPoolPercentage;
+BOOLEAN MmProtectFreedNonPagedPool;
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
index 7f2646f..6f5df91 100644 (file)
@@ -36,8 +36,9 @@
 /* The first array contains ReactOS PFNs, the second contains ARM3 PFNs */
 PPHYSICAL_PAGE MmPfnDatabase[2];
 
-ULONG MmAvailablePages;
-ULONG MmResidentAvailablePages;
+PFN_NUMBER MmAvailablePages;
+PFN_NUMBER MmResidentAvailablePages;
+PFN_NUMBER MmResidentAvailableAtInit;
 
 SIZE_T MmTotalCommitLimit;
 SIZE_T MmTotalCommittedPages;
index 8a9fd42..a03ce8e 100644 (file)
@@ -398,15 +398,12 @@ MmInitSystem(IN ULONG Phase,
         /* Initialize paged pool */
         MmInitializePagedPool();
         
+        /* Initialize the loaded module list */
+        MiInitializeLoadedModuleList(LoaderBlock);
+        
         /* Initialize working sets */
         MiInitializeUserPfnBitmap();
         MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
-
-        /* Reload boot drivers */
-        MiReloadBootLoadedDrivers(LoaderBlock);
-
-        /* Initialize the loaded module list */
-        MiInitializeLoadedModuleList(LoaderBlock);
     }
     else if (Phase == 1)
     {
index 1af2fac..1ea2c41 100644 (file)
@@ -86,6 +86,8 @@ ULONG MiFreeSwapPages;
 /* Number of pages that have been allocated for swapping */
 ULONG MiUsedSwapPages;
 
+BOOLEAN MmZeroPageFile;
+
 /*
  * Number of pages that have been reserved for swapping but not yet allocated
  */
index 582af62..fc70895 100644 (file)
@@ -71,6 +71,8 @@ MM_SECTION_PAGEOUT_CONTEXT;
 
 POBJECT_TYPE MmSectionObjectType = NULL;
 
+BOOLEAN MmAllocationFragment;
+
 ULONG_PTR MmSubsectionBase;
 
 static GENERIC_MAPPING MmpSectionMapping = {
index 281a396..fcecf3c 100644 (file)
@@ -39,10 +39,17 @@ ERESOURCE PsLoadedModuleResource;
 ULONG_PTR PsNtosImageBase;
 KMUTANT MmSystemLoadLock;
 
+PFN_NUMBER MmTotalSystemDriverPages;
+
 PVOID MmUnloadedDrivers;
 PVOID MmLastUnloadedDrivers;
-PVOID MmTriageActionTaken;
-PVOID KernelVerifier;
+
+BOOLEAN MmMakeLowMemory;
+BOOLEAN MmEnforceWriteProtection = TRUE;
+
+PMMPTE MiKernelResourceStartPte, MiKernelResourceEndPte;
+ULONG_PTR ExPoolCodeStart, ExPoolCodeEnd, MmPoolCodeStart, MmPoolCodeEnd;
+ULONG_PTR MmPteCodeStart, MmPteCodeEnd;
 
 /* FUNCTIONS ******************************************************************/
 
@@ -188,120 +195,6 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr,
     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,
@@ -440,6 +333,200 @@ MmCallDllInitialize(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
     return Status;
 }
 
+BOOLEAN
+NTAPI
+MiCallDllUnloadAndUnloadDll(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
+{
+    NTSTATUS Status;
+    PMM_DLL_UNLOAD Func;
+    PAGED_CODE();
+
+    /* Get the unload routine */
+    Func = (PMM_DLL_UNLOAD)MiLocateExportName(LdrEntry->DllBase, "DllUnload");
+    if (!Func) return FALSE;
+
+    /* Call it and check for success */
+    Status = Func();
+    if (!NT_SUCCESS(Status)) return FALSE;
+
+    /* Lie about the load count so we can unload the image */
+    ASSERT(LdrEntry->LoadCount == 0);
+    LdrEntry->LoadCount = 1;
+
+    /* Unload it and return true */
+    MmUnloadSystemImage(LdrEntry);
+    return TRUE;
+}
+
+NTSTATUS
+NTAPI
+MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
+{
+    SIZE_T i;
+    LOAD_IMPORTS SingleEntry;
+    PLDR_DATA_TABLE_ENTRY LdrEntry;
+    PVOID CurrentImports;
+    PAGED_CODE();
+
+    /* Check if there's no imports or if we're a boot driver */
+    if ((ImportList == MM_SYSLDR_NO_IMPORTS) ||
+        (ImportList == MM_SYSLDR_BOOT_LOADED) ||
+        (ImportList->Count == 0))
+    {
+        /* Then there's nothing to do */
+        return STATUS_SUCCESS;
+    }
+    
+    /* Check for single-entry */
+    if ((ULONG_PTR)ImportList & MM_SYSLDR_SINGLE_ENTRY)
+    {
+        /* Set it up */
+        SingleEntry.Count = 1;
+        SingleEntry.Entry[0] = (PVOID)((ULONG_PTR)ImportList &~ MM_SYSLDR_SINGLE_ENTRY);
+        
+        /* Use this as the import list */
+        ImportList = &SingleEntry;
+    }
+
+    /* Loop the import list */
+    for (i = 0; (i < ImportList->Count) && (ImportList->Entry[i]); i++)
+    {
+        /* Get the entry */
+        LdrEntry = ImportList->Entry[i];
+        DPRINT1("%wZ <%wZ>\n", &LdrEntry->FullDllName, &LdrEntry->BaseDllName);
+        
+        /* Skip boot loaded images */
+        if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) continue;
+        
+        /* Dereference the entry */
+        ASSERT(LdrEntry->LoadCount >= 1);
+        if (!--LdrEntry->LoadCount)
+        {
+            /* Save the import data in case unload fails */
+            CurrentImports = LdrEntry->LoadedImports;
+            
+            /* This is the last entry */
+            LdrEntry->LoadedImports = MM_SYSLDR_NO_IMPORTS;
+            if (MiCallDllUnloadAndUnloadDll(LdrEntry))
+            {
+                /* Unloading worked, parse this DLL's imports too */
+                MiDereferenceImports(CurrentImports);
+                
+                /* Check if we had valid imports */
+                if ((CurrentImports != MM_SYSLDR_BOOT_LOADED) ||
+                    (CurrentImports != MM_SYSLDR_NO_IMPORTS) ||
+                    !((ULONG_PTR)LdrEntry->LoadedImports & MM_SYSLDR_SINGLE_ENTRY))
+                {
+                    /* Free them */
+                    ExFreePool(CurrentImports);
+                }
+            }
+            else
+            {
+                /* Unload failed, restore imports */
+                LdrEntry->LoadedImports = CurrentImports;
+            }
+        }
+    }
+    
+    /* Done */
+    return STATUS_SUCCESS;
+}
+
+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 == MM_SYSLDR_BOOT_LOADED) ||
+        (LdrEntry->LoadedImports == MM_SYSLDR_NO_IMPORTS) ||
+        ((ULONG_PTR)LdrEntry->LoadedImports & MM_SYSLDR_SINGLE_ENTRY))
+    {
+        /* Nothing to do */
+        return;
+    }
+
+    /* Otherwise, free the import list */
+    ExFreePool(LdrEntry->LoadedImports);
+    LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
+}
+
+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];
+
+    /* Validate the ordinal */
+    if (Ordinal >= ExportDirectory->NumberOfFunctions) return NULL;
+
+    /* 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;
+}
+
 VOID
 NTAPI
 MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
@@ -474,9 +561,9 @@ MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
     ULONG_PTR OldBaseTop, Delta;
     PLDR_DATA_TABLE_ENTRY LdrEntry;
     PLIST_ENTRY NextEntry;
-    ULONG ImportSize;
+    ULONG ImportSize, i;
+    PULONG_PTR ImageThunk;
     PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
-    PULONG ImageThunk;
 
     /* Calculate the top and delta */
     OldBaseTop = (ULONG_PTR)OldBase + Size - 1;
@@ -491,8 +578,30 @@ MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
         LdrEntry = CONTAINING_RECORD(NextEntry,
                                      LDR_DATA_TABLE_ENTRY,
                                      InLoadOrderLinks);
+#ifdef _WORKING_LINKER_
+        /* Get the IAT */
+        ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
+                                                  TRUE,
+                                                  IMAGE_DIRECTORY_ENTRY_IAT,
+                                                  &ImportSize);
+        if (!ImageThunk) continue;
 
+        /* Make sure we have an IAT */
+        DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
+        for (i = 0; i < ImportSize; i++, 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;
+            }
+        }
+#else
         /* Get the import table */
+        i = ImportSize;
         ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
                                                         TRUE,
                                                         IMAGE_DIRECTORY_ENTRY_IMPORT,
@@ -525,6 +634,7 @@ MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
             /* Go to the next import */
             ImportDescriptor++;
         }
+#endif
     }
 }
 
@@ -592,7 +702,7 @@ MiSnapThunk(IN PVOID DllBase,
         /* Get the hint and check if it's valid */
         Hint = NameImport->Hint;
         if ((Hint < ExportDirectory->NumberOfNames) &&
-            !(strcmp((PCHAR) NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
+            !(strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
         {
             /* We have a match, get the ordinal number from here */
             Ordinal = OrdinalTable[Hint];
@@ -763,7 +873,7 @@ MmUnloadSystemImage(IN PVOID ImageHandle)
                           NULL);
 
     /* Check if this driver was loaded at boot and didn't get imports parsed */
-    if (LdrEntry->LoadedImports == (PVOID)-1) goto Done;
+    if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) goto Done;
 
     /* We should still be alive */
     ASSERT(LdrEntry->LoadCount != 0);
@@ -790,6 +900,7 @@ MmUnloadSystemImage(IN PVOID ImageHandle)
     }
 
     /* FIXME: Free the driver */
+    DPRINT1("Leaking driver: %wZ\n", &LdrEntry->BaseDllName);
     //MmFreeSection(LdrEntry->DllBase);
 
     /* Check if we're linked in */
@@ -860,7 +971,7 @@ MiResolveImageReferences(IN PVOID ImageBase,
            __FUNCTION__, ImageBase, ImageFileDirectory);
 
     /* Assume no imports */
-    *LoadImports = (PVOID)-2;
+    *LoadImports = MM_SYSLDR_NO_IMPORTS;
 
     /* Get the import descriptor */
     ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,
@@ -885,11 +996,12 @@ MiResolveImageReferences(IN PVOID ImageBase,
         LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
         LoadedImports = ExAllocatePoolWithTag(PagedPool,
                                               LoadedImportsSize,
-                                              TAG_LDR_WSTR);
+                                              'TDmM');
         if (LoadedImports)
         {
             /* Zero it */
             RtlZeroMemory(LoadedImports, LoadedImportsSize);
+            LoadedImports->Count = ImportCount;
         }
     }
     else
@@ -909,10 +1021,12 @@ MiResolveImageReferences(IN PVOID ImageBase,
         GdiLink = GdiLink |
                   !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1));
 
-        /* We can also allow dxapi */
+        /* We can also allow dxapi (for Windows compat, allow IRT and coverage )*/
         NormalLink = NormalLink |
                      ((_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) &&
-                      (_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)));
+                      (_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)) &&
+                      (_strnicmp(ImportName, "coverage", sizeof("coverage") - 1)) &&
+                      (_strnicmp(ImportName, "irt", sizeof("irt") - 1)));
 
         /* Check if this is a valid GDI driver */
         if ((GdiLink) && (NormalLink))
@@ -923,7 +1037,21 @@ MiResolveImageReferences(IN PVOID ImageBase,
             return STATUS_PROCEDURE_NOT_FOUND;
         }
 
-        /* Check if this is a "core" import, which doesn't get referenced */
+        /* Check for user-mode printer or video card drivers, which don't belong */
+        if (!(_strnicmp(ImportName, "ntdll", sizeof("ntdll") - 1)) ||
+            !(_strnicmp(ImportName, "winsrv", sizeof("winsrv") - 1)) ||
+            !(_strnicmp(ImportName, "advapi32", sizeof("advapi32") - 1)) ||
+            !(_strnicmp(ImportName, "kernel32", sizeof("kernel32") - 1)) ||
+            !(_strnicmp(ImportName, "user32", sizeof("user32") - 1)) ||
+            !(_strnicmp(ImportName, "gdi32", sizeof("gdi32") - 1)))
+        {
+            /* This is not kernel code */
+            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)))
@@ -999,7 +1127,7 @@ CheckDllState:
                                     sizeof(UNICODE_NULL);
             DllName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
                                                    DllName.MaximumLength,
-                                                   TAG_LDR_WSTR);
+                                                   'TDmM');
             if (DllName.Buffer)
             {
                 /* Setup the base length and copy it */
@@ -1011,13 +1139,13 @@ CheckDllState:
                 /* Now add the import name and null-terminate it */
                 RtlAppendStringToString((PSTRING)&DllName,
                                         (PSTRING)&NameString);
-                DllName.Buffer[(DllName.MaximumLength - 1) /  sizeof(WCHAR)] = UNICODE_NULL;
+                DllName.Buffer[(DllName.MaximumLength - 1) / sizeof(WCHAR)] = UNICODE_NULL;
 
                 /* Load the image */
                 Status = MmLoadSystemImage(&DllName,
                                            NamePrefix,
                                            NULL,
-                                           0,
+                                           FALSE,
                                            (PVOID)&DllEntry,
                                            &DllBase);
                 if (NT_SUCCESS(Status))
@@ -1080,8 +1208,8 @@ CheckDllState:
             if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
             {
                 /* Add the entry */
-                LoadedImports->Entry[LoadedImports->Count] = LdrEntry;
-                LoadedImports->Count++;
+                LoadedImports->Entry[ImportCount] = LdrEntry;
+                ImportCount++;
             }
         }
 
@@ -1150,7 +1278,8 @@ CheckDllState:
             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);
+                ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] |
+                                      MM_SYSLDR_SINGLE_ENTRY);
                 ImportCount++;
             }
         }
@@ -1160,7 +1289,7 @@ CheckDllState:
         {
             /* Free the list and set it to no imports */
             ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
-            LoadedImports = (PVOID)-2;
+            LoadedImports = MM_SYSLDR_NO_IMPORTS;
         }
         else if (ImportCount == 1)
         {
@@ -1174,7 +1303,7 @@ CheckDllState:
             LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
             NewImports = ExAllocatePoolWithTag(PagedPool,
                                                LoadedImportsSize,
-                                               TAG_LDR_WSTR);
+                                               'TDmM');
             if (NewImports)
             {
                 /* Set count */
@@ -1383,6 +1512,331 @@ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     }
 }
 
+NTSTATUS
+NTAPI
+MiBuildImportsForBootDrivers(VOID)
+{
+    PLIST_ENTRY NextEntry, NextEntry2;
+    PLDR_DATA_TABLE_ENTRY LdrEntry, KernelEntry, HalEntry, LdrEntry2, LastEntry;
+    PLDR_DATA_TABLE_ENTRY* EntryArray;
+    UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
+    UNICODE_STRING HalName = RTL_CONSTANT_STRING(L"hal.dll");
+    PLOAD_IMPORTS LoadedImports;
+    ULONG LoadedImportsSize, ImportSize;
+    PULONG_PTR ImageThunk;
+    ULONG_PTR DllBase, DllEnd;
+    ULONG Modules = 0, i, j = 0;
+    PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
+    
+    /* Initialize variables */
+    KernelEntry = HalEntry = LastEntry = NULL;
+
+    /* Loop the loaded module list... we are early enough that no lock is needed */
+    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 */
+            KernelEntry = LdrEntry;
+        }
+        else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
+        {
+            /* Found it */
+            HalEntry = LdrEntry;
+        }
+        
+        /* Check if this is a driver DLL */
+        if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
+        {
+            /* Check if this is the HAL or kernel */
+            if ((LdrEntry == HalEntry) || (LdrEntry == KernelEntry))
+            {
+                /* Add a reference */
+                LdrEntry->LoadCount = 1;
+            }
+            else
+            {
+                /* No referencing needed */
+                LdrEntry->LoadCount = 0;
+            }
+        }
+        else
+        {
+            /* No referencing needed */
+            LdrEntry->LoadCount = 0;    
+        }
+        
+        /* Remember this came from the loader */
+        LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
+
+        /* Keep looping */
+        NextEntry = NextEntry->Flink;
+        Modules++;
+    }
+    
+    /* We must have at least found the kernel and HAL */
+    if (!(HalEntry) || (!KernelEntry)) return STATUS_NOT_FOUND;
+    
+    /* Allocate the list */
+    EntryArray = ExAllocatePoolWithTag(PagedPool, Modules * sizeof(PVOID), 'TDmM');
+    if (!EntryArray) return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* Loop the loaded module list again */
+    NextEntry = PsLoadedModuleList.Flink;
+    while (NextEntry != &PsLoadedModuleList)
+    {
+        /* Get the entry */
+        LdrEntry = CONTAINING_RECORD(NextEntry,
+                                     LDR_DATA_TABLE_ENTRY,
+                                     InLoadOrderLinks);
+#ifdef _WORKING_LOADER_
+        /* Get its imports */
+        ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
+                                                  TRUE,
+                                                  IMAGE_DIRECTORY_ENTRY_IAT,
+                                                  &ImportSize);
+        if (!ImageThunk)                                                
+#else
+        /* Get its imports */
+        ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
+                                                        TRUE,
+                                                        IMAGE_DIRECTORY_ENTRY_IMPORT,
+                                                        &ImportSize);
+        if (!ImportDescriptor)
+#endif
+        {
+            /* None present */
+            LdrEntry->LoadedImports = MM_SYSLDR_NO_IMPORTS;
+            NextEntry = NextEntry->Flink;
+            continue;
+        }
+        
+        /* Clear the list and count the number of IAT thunks */
+        RtlZeroMemory(EntryArray, Modules * sizeof(PVOID));
+#ifdef _WORKING_LOADER_
+        ImportSize /= sizeof(ULONG_PTR);
+        
+        /* Scan the thunks */
+        for (i = 0, DllBase = 0, DllEnd = 0; i < ImportSize; i++, ImageThunk++)
+#else
+        i = DllBase = DllEnd = 0;
+        while ((ImportDescriptor->Name) &&
+               (ImportDescriptor->OriginalFirstThunk))
+        {
+            /* Get the image thunk */
+            ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
+                                 ImportDescriptor->FirstThunk);
+            while (*ImageThunk)
+#endif
+            {
+            /* Do we already have an address? */
+            if (DllBase)
+            {
+                /* Is the thunk in the same address? */
+                if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
+                {
+                    /* Skip it, we already have a reference for it */
+                    ASSERT(EntryArray[j]);
+                    ImageThunk++;
+                    continue;
+                }
+            }
+            
+            /* Loop the loaded module list to locate this address owner */
+            j = 0;
+            NextEntry2 = PsLoadedModuleList.Flink;
+            while (NextEntry2 != &PsLoadedModuleList)
+            {
+                /* Get the entry */
+                LdrEntry2 = CONTAINING_RECORD(NextEntry2,
+                                              LDR_DATA_TABLE_ENTRY,
+                                              InLoadOrderLinks);
+                                              
+                /* Get the address range for this module */
+                DllBase = (ULONG_PTR)LdrEntry2->DllBase;
+                DllEnd = DllBase + LdrEntry2->SizeOfImage;
+                
+                /* Check if this IAT entry matches it */
+                if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
+                {
+                    /* Save it */
+                    //DPRINT1("Found imported dll: %wZ\n", &LdrEntry2->BaseDllName);
+                    EntryArray[j] = LdrEntry2;
+                    break;
+                }
+                
+                /* Keep searching */
+                NextEntry2 = NextEntry2->Flink;
+                j++;
+            }
+            
+            /* Do we have a thunk outside the range? */
+            if ((*ImageThunk < DllBase) || (*ImageThunk >= DllEnd))
+            {
+                /* Could be 0... */
+                if (*ImageThunk)
+                {
+                    /* Should not be happening */
+                    DPRINT1("Broken IAT entry for %p at %p (%lx)\n",
+                            LdrEntry, ImageThunk, *ImageThunk);
+                    ASSERT(FALSE);
+                }
+                
+                /* Reset if we hit this */
+                DllBase = 0;
+            }
+#ifndef _WORKING_LOADER_
+            ImageThunk++;
+            }
+        
+            i++;
+            ImportDescriptor++;
+#endif
+        }
+        
+        /* Now scan how many imports we really have */
+        for (i = 0, ImportSize = 0; i < Modules; i++)
+        {
+            /* Skip HAL and kernel */
+            if ((EntryArray[i]) &&
+                (EntryArray[i] != HalEntry) &&
+                (EntryArray[i] != KernelEntry))
+            {
+                /* A valid reference */
+                LastEntry = EntryArray[i];
+                ImportSize++;
+            }
+        }
+        
+        /* Do we have any imports after all? */
+        if (!ImportSize)
+        {
+            /* No */
+            LdrEntry->LoadedImports = MM_SYSLDR_NO_IMPORTS;
+        }
+        else if (ImportSize == 1)
+        {
+            /* A single entry import */
+            LdrEntry->LoadedImports = (PVOID)((ULONG_PTR)LastEntry | MM_SYSLDR_SINGLE_ENTRY);
+            LastEntry->LoadCount++;
+        }
+        else
+        {
+            /* We need an import table */
+            LoadedImportsSize = ImportSize * sizeof(PVOID) + sizeof(SIZE_T);
+            LoadedImports = ExAllocatePoolWithTag(PagedPool,
+                                                  LoadedImportsSize,
+                                                  'TDmM');
+            ASSERT(LoadedImports);
+            
+            /* Save the count */
+            LoadedImports->Count = ImportSize;
+            
+            /* Now copy all imports */
+            for (i = 0, j = 0; i < Modules; i++)
+            {
+                /* Skip HAL and kernel */
+                if ((EntryArray[i]) &&
+                    (EntryArray[i] != HalEntry) &&
+                    (EntryArray[i] != KernelEntry))
+                {
+                    /* A valid reference */
+                    //DPRINT1("Found valid entry: %p\n", EntryArray[i]);
+                    LoadedImports->Entry[j] = EntryArray[i];
+                    EntryArray[i]->LoadCount++;
+                    j++;
+                }
+            }
+            
+            /* Should had as many entries as we expected */
+            ASSERT(j == ImportSize);
+            LdrEntry->LoadedImports = LoadedImports;
+        }
+        
+        /* Next */
+        NextEntry = NextEntry->Flink;
+    }
+    
+    /* Free the initial array */
+    ExFreePool(EntryArray);
+    
+    /* FIXME: Might not need to keep the HAL/Kernel imports around */
+    
+    /* Kernel and HAL are loaded at boot */
+    KernelEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
+    HalEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
+    
+    /* All worked well */
+    return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
+{
+    ULONG_PTR DllBase;
+    PIMAGE_NT_HEADERS NtHeaders;
+    PIMAGE_SECTION_HEADER SectionHeader;
+    ULONG Sections, Size;
+    
+    /* Get the kernel section header */
+    DllBase = (ULONG_PTR)LdrEntry->DllBase;
+    NtHeaders = RtlImageNtHeader((PVOID)DllBase);
+    SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
+
+    /* Loop all the sections */
+    Sections = NtHeaders->FileHeader.NumberOfSections;
+    while (Sections)
+    {
+        /* Grab the size of the section */
+        Size = max(SectionHeader->SizeOfRawData, SectionHeader->Misc.VirtualSize);
+        
+        /* Check for .RSRC section */
+        if (*(PULONG)SectionHeader->Name == 'rsr.')
+        {
+            /* Remember the PTEs so we can modify them later */
+            MiKernelResourceStartPte = MiAddressToPte(DllBase +
+                                                      SectionHeader->VirtualAddress);
+            MiKernelResourceEndPte = MiKernelResourceStartPte +
+                                     BYTES_TO_PAGES(SectionHeader->VirtualAddress + Size);
+        }
+        else if (*(PULONG)SectionHeader->Name == 'LOOP')
+        {
+            /* POOLCODE vs. POOLMI */
+            if (*(PULONG)&SectionHeader->Name[4] == 'EDOC')
+            {
+                /* Found Ex* Pool code */
+                ExPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
+                ExPoolCodeEnd = ExPoolCodeStart + Size;
+            }
+            else if (*(PUSHORT)&SectionHeader->Name[4] == 'MI')
+            {
+                /* Found Mm* Pool code */
+                MmPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
+                MmPoolCodeEnd = ExPoolCodeStart + Size;                
+            }
+        }
+        else if ((*(PULONG)SectionHeader->Name == 'YSIM') &&
+                 (*(PULONG)&SectionHeader->Name[4] == 'ETPS'))
+        {
+            /* Found MISYSPTE (Mm System PTE code)*/
+            MmPteCodeStart = DllBase + SectionHeader->VirtualAddress;
+            MmPteCodeEnd = ExPoolCodeStart + Size;
+        }
+        
+        /* Keep going */
+        Sections--;
+        SectionHeader++;
+    }
+}
+
 BOOLEAN
 NTAPI
 MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
@@ -1403,6 +1857,9 @@ MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
                                  LDR_DATA_TABLE_ENTRY,
                                  InLoadOrderLinks);
     PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
+    
+    /* Locate resource section, pool code, and system pte code */
+    MiLocateKernelSections(LdrEntry);
 
     /* Loop the loader block */
     while (NextEntry != ListHead)
@@ -1416,7 +1873,7 @@ MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
         if (!RtlImageNtHeader(LdrEntry->DllBase))
         {
             /* Skip this entry */
-            NextEntry= NextEntry->Flink;
+            NextEntry = NextEntry->Flink;
             continue;
         }
 
@@ -1459,12 +1916,441 @@ MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     }
 
     /* Build the import lists for the boot drivers */
-    //MiBuildImportsForBootDrivers();
+    MiBuildImportsForBootDrivers();
 
     /* We're done */
     return TRUE;
 }
 
+LOGICAL
+NTAPI
+MiUseLargeDriverPage(IN ULONG NumberOfPtes,
+                     IN OUT PVOID *ImageBaseAddress,
+                     IN PUNICODE_STRING BaseImageName,
+                     IN BOOLEAN BootDriver)
+{
+    PLIST_ENTRY NextEntry;
+    BOOLEAN DriverFound = FALSE;
+    PMI_LARGE_PAGE_DRIVER_ENTRY LargePageDriverEntry;
+    ASSERT(KeGetCurrentIrql () <= APC_LEVEL);
+    ASSERT(*ImageBaseAddress >= MmSystemRangeStart);
+
+#ifdef _X86_
+    if (!(KeFeatureBits & KF_LARGE_PAGE)) return FALSE;
+    if (!(__readcr4() & CR4_PSE)) return FALSE;
+#endif
+
+    /* Make sure there's enough system PTEs for a large page driver */
+    if (MmTotalFreeSystemPtes[SystemPteSpace] < (16 * (PDE_MAPPED_VA >> PAGE_SHIFT)))
+    {
+        return FALSE;
+    }
+
+    /* This happens if the registry key had a "*" (wildcard) in it */
+    if (MiLargePageAllDrivers == 0)
+    {
+        /* It didn't, so scan the list */
+        NextEntry = MiLargePageDriverList.Flink;
+        while (NextEntry != &MiLargePageDriverList)
+        {
+            /* Check if the driver name matches */
+            LargePageDriverEntry = CONTAINING_RECORD(NextEntry,
+                                                     MI_LARGE_PAGE_DRIVER_ENTRY,
+                                                     Links);
+            if (RtlEqualUnicodeString(BaseImageName,
+                                      &LargePageDriverEntry->BaseName,
+                                      TRUE))
+            {
+                /* Enable large pages for this driver */
+                DriverFound = TRUE;
+                break;
+            }
+
+            /* Keep trying */
+            NextEntry = NextEntry->Flink;
+        }
+        
+        /* If we didn't find the driver, it doesn't need large pages */
+        if (DriverFound == FALSE) return FALSE;
+    }
+    /* Nothing to do yet */
+    DPRINT1("Large pages not supported!\n");
+    return FALSE;
+}
+
+ULONG
+NTAPI
+MiComputeDriverProtection(IN BOOLEAN SessionSpace,
+                          IN ULONG SectionProtection)
+{
+    ULONG Protection = MM_ZERO_ACCESS;
+    
+    /* Check if the caller gave anything */
+    if (SectionProtection)
+    {
+        /* Always turn on execute access */
+        SectionProtection |= IMAGE_SCN_MEM_EXECUTE;
+        
+        /* Check if the registry setting is on or not */
+        if (!MmEnforceWriteProtection)
+        {
+            /* Turn on write access too */
+            SectionProtection |= (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE);
+        }
+    }
+    
+    /* Convert to internal PTE flags */
+    if (SectionProtection & IMAGE_SCN_MEM_EXECUTE) Protection |= MM_EXECUTE;
+    if (SectionProtection & IMAGE_SCN_MEM_READ) Protection |= MM_READONLY;
+    
+    /* Check for write access */
+    if (SectionProtection & IMAGE_SCN_MEM_WRITE)
+    {
+        /* Session space is not supported */
+        if (SessionSpace)
+        {
+            DPRINT1("Session drivers not supported\n");
+            ASSERT(SessionSpace == FALSE);
+        }
+        else
+        {
+            /* Convert to internal PTE flag */
+            Protection = (Protection & MM_EXECUTE) ? MM_EXECUTE_READWRITE : MM_READWRITE;
+        }
+    }
+    
+    /* If there's no access at all by now, convert to internal no access flag */
+    if (Protection == MM_ZERO_ACCESS) Protection = MM_NOACCESS;
+    
+    /* Return the computed PTE protection */
+    return Protection;
+}
+
+VOID
+NTAPI
+MiSetSystemCodeProtection(IN PMMPTE FirstPte,
+                          IN PMMPTE LastPte,
+                          IN ULONG ProtectionMask)
+{
+    /* I'm afraid to introduce regressions at the moment... */
+    return;
+}
+
+VOID
+NTAPI
+MiWriteProtectSystemImage(IN PVOID ImageBase)
+{
+    PIMAGE_NT_HEADERS NtHeaders;
+    PIMAGE_SECTION_HEADER Section;
+    PFN_NUMBER DriverPages;
+    ULONG CurrentProtection, SectionProtection, CombinedProtection, ProtectionMask;
+    ULONG Sections, Size;
+    ULONG_PTR BaseAddress, CurrentAddress;
+    PMMPTE PointerPte, StartPte, LastPte, CurrentPte, ComboPte = NULL;
+    ULONG CurrentMask, CombinedMask = 0;
+    PAGED_CODE();
+    
+    /* No need to write protect physical memory-backed drivers (large pages) */
+    if (MI_IS_PHYSICAL_ADDRESS(ImageBase)) return;
+    
+    /* Get the image headers */
+    NtHeaders = RtlImageNtHeader(ImageBase);
+    if (!NtHeaders) return;
+    
+    /* Check if this is a session driver or not */
+    if (!MI_IS_SESSION_ADDRESS(ImageBase))
+    {
+        /* Don't touch NT4 drivers */
+        if (NtHeaders->OptionalHeader.MajorOperatingSystemVersion < 5) return;
+        if (NtHeaders->OptionalHeader.MajorImageVersion < 5) return;
+    }
+    else
+    {
+        /* Not supported */
+        DPRINT1("Session drivers not supported\n");
+        ASSERT(FALSE);
+    }
+    
+    /* These are the only protection masks we care about */
+    ProtectionMask = IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
+    
+    /* Calculate the number of pages this driver is occupying */
+    DriverPages = BYTES_TO_PAGES(NtHeaders->OptionalHeader.SizeOfImage);
+    
+    /* Get the number of sections and the first section header */
+    Sections = NtHeaders->FileHeader.NumberOfSections;
+    ASSERT(Sections != 0);
+    Section = IMAGE_FIRST_SECTION(NtHeaders);
+
+    /* Loop all the sections */
+    CurrentAddress = (ULONG_PTR)ImageBase;
+    while (Sections)
+    {
+        /* Get the section size */
+        Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
+        
+        /* Get its virtual address */
+        BaseAddress = (ULONG_PTR)ImageBase + Section->VirtualAddress;
+        if (BaseAddress < CurrentAddress)
+        {
+            /* Windows doesn't like these */
+            DPRINT1("Badly linked image!\n");
+            return;
+        }
+        
+        /* Remember the current address */
+        CurrentAddress = BaseAddress + Size - 1;
+        
+        /* Next */
+        Sections--;
+        Section++;
+    }
+    
+    /* Get the number of sections and the first section header */
+    Sections = NtHeaders->FileHeader.NumberOfSections;
+    ASSERT(Sections != 0);
+    Section = IMAGE_FIRST_SECTION(NtHeaders);
+    
+    /* Set the address at the end to initialize the loop */
+    CurrentAddress = (ULONG_PTR)Section + Sections - 1;
+    CurrentProtection = IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ;
+    
+    /* Set the PTE points for the image, and loop its sections */
+    StartPte = MiAddressToPte(ImageBase);
+    LastPte = StartPte + DriverPages;
+    while (Sections)
+    {
+        /* Get the section size */
+        Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
+        
+        /* Get its virtual address and PTE */
+        BaseAddress = (ULONG_PTR)ImageBase + Section->VirtualAddress;
+        PointerPte = MiAddressToPte(BaseAddress);
+        
+        /* Check if we were already protecting a run, and found a new run */
+        if ((ComboPte) && (PointerPte > ComboPte))
+        {
+            /* Compute protection */
+            CombinedMask = MiComputeDriverProtection(FALSE, CombinedProtection);
+            
+            /* Set it */
+            MiSetSystemCodeProtection(ComboPte, ComboPte, CombinedMask);
+            
+            /* Check for overlap */
+            if (ComboPte == StartPte) StartPte++;
+            
+            /* One done, reset variables */
+            ComboPte = NULL;
+            CombinedProtection = 0;
+        }
+        
+        /* Break out when needed */
+        if (PointerPte >= LastPte) break;
+        
+        /* Get the requested protection from the image header */
+        SectionProtection = Section->Characteristics & ProtectionMask;
+        if (SectionProtection == CurrentProtection)
+        {
+            /* Same protection, so merge the request */
+            CurrentAddress = BaseAddress + Size - 1;
+        
+            /* Next */
+            Sections--;
+            Section++;
+            continue;
+        }
+        
+        /* This is now a new section, so close up the old one */
+        CurrentPte = MiAddressToPte(CurrentAddress);
+        
+        /* Check for overlap */
+        if (CurrentPte == PointerPte)
+        {
+            /* Skip the last PTE, since it overlaps with us */
+            CurrentPte--;
+    
+            /* And set the PTE we will merge with */
+            ASSERT((ComboPte == NULL) || (ComboPte == PointerPte));
+            ComboPte = PointerPte;
+            
+            /* Get the most flexible protection by merging both */
+            CombinedMask |= (SectionProtection | CurrentProtection);
+        }
+        
+        /* Loop any PTEs left */
+        if (CurrentPte >= StartPte)
+        {
+            /* Sanity check */
+            ASSERT(StartPte < LastPte);
+            
+            /* Make sure we don't overflow past the last PTE in the driver */
+            if (CurrentPte >= LastPte) CurrentPte = LastPte - 1;
+            ASSERT(CurrentPte >= StartPte);
+            
+            /* Compute the protection and set it */
+            CurrentMask = MiComputeDriverProtection(FALSE, CurrentProtection);
+            MiSetSystemCodeProtection(StartPte, CurrentPte, CurrentMask);
+        }
+        
+        /* Set new state */
+        StartPte = PointerPte;
+        CurrentAddress = BaseAddress + Size - 1;
+        CurrentProtection = SectionProtection;
+        
+        /* Next */
+        Sections--;
+        Section++;
+    }
+    
+    /* Is there a leftover section to merge? */
+    if (ComboPte)
+    {
+        /* Compute and set the protection */
+        CombinedMask = MiComputeDriverProtection(FALSE, CombinedProtection);
+        MiSetSystemCodeProtection(ComboPte, ComboPte, CombinedMask);
+        
+        /* Handle overlap */
+        if (ComboPte == StartPte) StartPte++;
+    }
+    
+    /* Finally, handle the last section */
+    CurrentPte = MiPteToAddress(CurrentAddress);
+    if ((StartPte < LastPte) && (CurrentPte >= StartPte))
+    {
+        /* Handle overlap */
+        if (CurrentPte >= LastPte) CurrentPte = LastPte - 1;
+        ASSERT(CurrentPte >= StartPte);
+        
+        /* Compute and set the protection */
+        CurrentMask = MiComputeDriverProtection(FALSE, CurrentProtection);
+        MiSetSystemCodeProtection(StartPte, CurrentPte, CurrentMask);
+    }
+}
+
+VOID
+NTAPI
+MiSetPagingOfDriver(IN PMMPTE PointerPte,
+                    IN PMMPTE LastPte)
+{
+    PVOID ImageBase;
+    PETHREAD CurrentThread;
+    PFN_NUMBER PageCount = 0, PageFrameIndex;
+    PMMPFN Pfn1;
+    PAGED_CODE();
+    
+    /* Get the driver's base address */
+    ImageBase = MiPteToAddress(PointerPte);
+    ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(ImageBase) == FALSE);
+    
+    /* If this is a large page, it's stuck in physical memory */
+    if (MI_IS_PHYSICAL_ADDRESS(ImageBase)) return;
+
+    /* We should lock the system working set -- we don't have one yet, so just be consistent */
+    CurrentThread = PsGetCurrentThread();
+    KeEnterGuardedRegion();
+    ASSERT((CurrentThread->OwnsSystemWorkingSetExclusive == 0) &&
+           (CurrentThread->OwnsSystemWorkingSetShared == 0));
+    CurrentThread->OwnsSystemWorkingSetExclusive = 1;
+    
+    /* Loop the PTEs */
+    while (PointerPte <= LastPte)
+    {
+        /* Check for valid PTE */
+        if (PointerPte->u.Hard.Valid == 1)
+        {
+            PageFrameIndex = PFN_FROM_PTE(PointerPte);
+            Pfn1 = MiGetPfnEntry(PageFrameIndex);
+            ASSERT(Pfn1->u2.ShareCount == 1);
+            
+            /* No working sets in ReactOS yet */
+            PageCount++;
+        }
+        
+        ImageBase = (PVOID)((ULONG_PTR)ImageBase + PAGE_SIZE);
+        PointerPte++;
+    }
+    
+    /* Release the working set "lock" */
+    ASSERT(KeAreAllApcsDisabled() == TRUE);
+    CurrentThread->OwnsSystemWorkingSetExclusive = 0;
+    KeLeaveGuardedRegion();
+    
+    /* Do we have any driver pages? */
+    if (PageCount)
+    {
+        /* Update counters */
+        InterlockedExchangeAdd((PLONG)&MmTotalSystemDriverPages, PageCount);
+    }
+}
+
+VOID
+NTAPI
+MiEnablePagingOfDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
+{
+    ULONG_PTR ImageBase;
+    PIMAGE_NT_HEADERS NtHeaders;
+    ULONG Sections, Alignment, Size;
+    PIMAGE_SECTION_HEADER Section;
+    PMMPTE PointerPte = NULL, LastPte = NULL;
+    if (MmDisablePagingExecutive) return;
+    
+    /* Get the driver base address and its NT header */
+    ImageBase = (ULONG_PTR)LdrEntry->DllBase;
+    NtHeaders = RtlImageNtHeader((PVOID)ImageBase);
+    if (!NtHeaders) return;
+    
+    /* Get the sections and their alignment */
+    Sections = NtHeaders->FileHeader.NumberOfSections;
+    Alignment = NtHeaders->OptionalHeader.SectionAlignment - 1;
+    
+    /* Loop each section */
+    Section = IMAGE_FIRST_SECTION(NtHeaders);
+    while (Sections)
+    {
+        /* Find PAGE or .edata */
+        if ((*(PULONG)Section->Name == 'EGAP') ||
+            (*(PULONG)Section->Name == 'ade.'))
+        {
+            /* Had we already done some work? */
+            if (!PointerPte)
+            {
+                /* Nope, setup the first PTE address */
+                PointerPte = MiAddressToPte(ROUND_TO_PAGES(ImageBase +
+                                                           Section->
+                                                           VirtualAddress));
+            }
+            
+            /* Compute the size */
+            Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
+            
+            /* Find the last PTE that maps this section */
+            LastPte = MiAddressToPte(ImageBase +
+                                     Section->VirtualAddress +
+                                     Alignment +
+                                     Size -
+                                     PAGE_SIZE);
+        }
+        else
+        {
+            /* Had we found a section before? */
+            if (PointerPte)
+            {
+                /* Mark it as pageable */
+                MiSetPagingOfDriver(PointerPte, LastPte);
+                PointerPte = NULL;
+            }
+        }
+        
+        /* Keep searching */
+        Sections--;
+        Section++;
+    }
+    
+    /* Handle the straggler */
+    if (PointerPte) MiSetPagingOfDriver(PointerPte, LastPte);
+}
+
 BOOLEAN
 NTAPI
 MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
@@ -1501,15 +2387,24 @@ MmCheckSystemImage(IN HANDLE ImageHandle,
     IO_STATUS_BLOCK IoStatusBlock;
     FILE_STANDARD_INFORMATION FileStandardInfo;
     KAPC_STATE ApcState;
+    PIMAGE_NT_HEADERS NtHeaders;
+    OBJECT_ATTRIBUTES ObjectAttributes;
     PAGED_CODE();
+    
+    /* Setup the object attributes */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               NULL,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
 
     /* Create a section for the DLL */
     Status = ZwCreateSection(&SectionHandle,
                              SECTION_MAP_EXECUTE,
-                             NULL,
+                             &ObjectAttributes,
                              NULL,
                              PAGE_EXECUTE,
-                             SEC_COMMIT,
+                             SEC_IMAGE,
                              ImageHandle);
     if (!NT_SUCCESS(Status)) return Status;
 
@@ -1541,17 +2436,35 @@ MmCheckSystemImage(IN HANDLE ImageHandle,
                                     &FileStandardInfo,
                                     sizeof(FileStandardInfo),
                                     FileStandardInformation);
-    if ( NT_SUCCESS(Status) )
+    if (NT_SUCCESS(Status))
     {
         /* First, verify the checksum */
         if (!LdrVerifyMappedImageMatchesChecksum(ViewBase,
-                                                 FileStandardInfo.
-                                                 EndOfFile.LowPart,
+                                                 ViewSize,
                                                  FileStandardInfo.
                                                  EndOfFile.LowPart))
         {
             /* Set checksum failure */
             Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
+            goto Fail;
+        }
+        
+        /* Make sure it's a real image */
+        NtHeaders = RtlImageNtHeader(ViewBase);
+        if (!NtHeaders)
+        {
+            /* Set checksum failure */
+            Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
+            goto Fail;
+        }
+        
+        /* Make sure it's for the correct architecture */
+        if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
+            (NtHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC))
+        {
+            /* Set protection failure */
+            Status = STATUS_INVALID_IMAGE_PROTECT;
+            goto Fail;
         }
 
         /* Check that it's a valid SMP image if we have more then one CPU */
@@ -1563,6 +2476,7 @@ MmCheckSystemImage(IN HANDLE ImageHandle,
     }
 
     /* Unmap the section, close the handle, and return status */
+Fail:
     ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
     KeUnstackDetachProcess(&ApcState);
     ZwClose(SectionHandle);
@@ -1587,7 +2501,7 @@ MmLoadSystemImage(IN PUNICODE_STRING FileName,
     UNICODE_STRING BaseName, BaseDirectory, PrefixName, UnicodeTemp;
     PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
     ULONG EntrySize, DriverSize;
-    PLOAD_IMPORTS LoadedImports = (PVOID)-2;
+    PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
     PCHAR MissingApiName, Buffer;
     PWCHAR MissingDriverName;
     HANDLE SectionHandle;
@@ -1611,7 +2525,7 @@ MmLoadSystemImage(IN PUNICODE_STRING FileName,
     }
 
     /* Allocate a buffer we'll use for names */
-    Buffer = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH, TAG_LDR_WSTR);
+    Buffer = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH, 'nLmM');
     if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
 
     /* Check for a separator */
@@ -1655,6 +2569,14 @@ MmLoadSystemImage(IN PUNICODE_STRING FileName,
 
     /* Check if we already have a name, use it instead */
     if (LoadedName) BaseName = *LoadedName;
+    
+    /* Check for loader snap debugging */
+    if (NtGlobalFlag & FLG_SHOW_LDR_SNAPS)
+    {
+        /* Print out standard string */
+        DPRINT1("MM:SYSLDR Loading %wZ (%wZ) %s\n",
+                &PrefixName, &BaseName, Flags ? "in session space" : "");
+    }
 
     /* Acquire the load lock */
 LoaderScan:
@@ -1750,7 +2672,7 @@ LoaderScan:
         Status = MmCheckSystemImage(FileHandle, FALSE);
         if ((Status == STATUS_IMAGE_CHECKSUM_MISMATCH) ||
             (Status == STATUS_IMAGE_MP_UP_MISMATCH) ||
-            (Status == STATUS_INVALID_IMAGE_FORMAT))
+            (Status == STATUS_INVALID_IMAGE_PROTECT))
         {
             /* Fail loading */
             goto Quickie;
@@ -1829,16 +2751,20 @@ LoaderScan:
         /* Check for success */
         if (NT_SUCCESS(Status))
         {
-            /* FIXME: Support large pages for drivers */
+            /* Support large pages for drivers */
+            MiUseLargeDriverPage(DriverSize / PAGE_SIZE,
+                                 &ModuleLoadBase,
+                                 &BaseName,
+                                 TRUE);
         }
 
         /* Dereference the section */
         ObDereferenceObject(Section);
         Section = NULL;
     }
-
-    /* Get the NT Header */
-    NtHeader = RtlImageNtHeader(ModuleLoadBase);
+    
+    /* Check for failure of the load earlier */
+    if (!NT_SUCCESS(Status)) goto Quickie;
 
     /* Relocate the driver */
     Status = LdrRelocateImageWithBias(ModuleLoadBase,
@@ -1849,6 +2775,10 @@ LoaderScan:
                                       STATUS_INVALID_IMAGE_FORMAT);
     if (!NT_SUCCESS(Status)) goto Quickie;
 
+    
+    /* Get the NT Header */
+    NtHeader = RtlImageNtHeader(ModuleLoadBase);
+
     /* Calculate the size we'll need for the entry and allocate it */
     EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
                 BaseName.Length +
@@ -1956,9 +2886,10 @@ LoaderScan:
     LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
     LdrEntry->LoadedImports = LoadedImports;
 
-    /* FIXME: Apply driver verifier */
+    /* FIXME: Call driver verifier's loader function */
 
-    /* FIXME: Write-protect the system image */
+    /* Write-protect the system image */
+    MiWriteProtectSystemImage(LdrEntry->DllBase);
 
     /* Check if notifications are enabled */
     if (PsImageNotifyEnabled)
@@ -2012,17 +2943,15 @@ LoaderScan:
         LdrEntry->Flags |= LDRP_DEBUG_SYMBOLS_LOADED;
     }
 
-    /* FIXME: Page the driver */
+    /* Page the driver */
     ASSERT(Section == NULL);
+    MiEnablePagingOfDriver(LdrEntry);
 
     /* Return pointers */
     *ModuleObject = LdrEntry;
     *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)
     {
@@ -2032,6 +2961,9 @@ Quickie:
         LockOwned = FALSE;
     }
 
+    /* If we have a file handle, close it */
+    if (FileHandle) ZwClose(FileHandle);
+
     /* Check if we had a prefix */
     if (NamePrefix) ExFreePool(PrefixName.Buffer);
 
@@ -2040,6 +2972,90 @@ Quickie:
     return Status;
 }
 
+PLDR_DATA_TABLE_ENTRY
+NTAPI
+MiLookupDataTableEntry(IN PVOID Address)
+{
+    PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
+    PLIST_ENTRY NextEntry;
+    PAGED_CODE();
+    
+    /* Loop entries */
+    NextEntry = PsLoadedModuleList.Flink;
+    do
+    {
+        /* Get the loader entry */
+        LdrEntry =  CONTAINING_RECORD(NextEntry,
+                                      LDR_DATA_TABLE_ENTRY,
+                                      InLoadOrderLinks);
+        
+        /* Check if the address matches */
+        if ((Address >= LdrEntry->DllBase) &&
+            (Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase +
+                               LdrEntry->SizeOfImage)))
+        {
+            /* Found a match */
+            FoundEntry = LdrEntry;
+            break;
+        }
+        
+        /* Move on */
+        NextEntry = NextEntry->Flink;
+    } while(NextEntry != &PsLoadedModuleList);
+    
+    /* Return the entry */
+    return FoundEntry;
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+/*
+ * @implemented
+ */
+PVOID
+NTAPI
+MmPageEntireDriver(IN PVOID AddressWithinSection)
+{
+    PMMPTE StartPte, EndPte;
+    PLDR_DATA_TABLE_ENTRY LdrEntry;
+    PAGED_CODE();
+
+    /* Get the loader entry */
+    LdrEntry = MiLookupDataTableEntry(AddressWithinSection);
+    if (!LdrEntry) return NULL;
+
+    /* Check if paging of kernel mode is disabled or if the driver is mapped as an image */
+    if ((MmDisablePagingExecutive) || (LdrEntry->SectionPointer))
+    {
+        /* Don't do anything, just return the base address */
+        return LdrEntry->DllBase;
+    }
+
+    /* Wait for active DPCs to finish before we page out the driver */
+    KeFlushQueuedDpcs();
+
+    /* Get the PTE range for the whole driver image */
+    StartPte = MiAddressToPte((ULONG_PTR)LdrEntry->DllBase);
+    EndPte = MiAddressToPte((ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage);
+
+    /* Enable paging for the PTE range */
+    ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(AddressWithinSection) == FALSE);
+    MiSetPagingOfDriver(StartPte, EndPte);
+
+    /* Return the base address */
+    return LdrEntry->DllBase;
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+NTAPI
+MmResetDriverPaging(IN PVOID AddressWithinSection)
+{
+    UNIMPLEMENTED;
+}
+
 /*
  * @implemented
  */
index a605ee1..5dc63c6 100644 (file)
                        <file>device.c</file>
                        <file>deviface.c</file>
                        <file>driver.c</file>
-                       <file>drvrlist.c</file>
                        <file>error.c</file>
                        <file>file.c</file>
                        <file>iocomp.c</file>
                <directory name="pnpmgr">
                        <file>plugplay.c</file>
                        <file>pnpdma.c</file>
+                       <file>pnpinit.c</file>
                        <file>pnpmgr.c</file>
                        <file>pnpnotify.c</file>
                        <file>pnpreport.c</file>
+                       <file>pnpres.c</file>
                        <file>pnproot.c</file>
+                       <file>pnputil.c</file>
                </directory>
        </directory>
        <if property="_WINKD_" value="0">
                        <file>expool.c</file>
                        <file>hypermap.c</file>
                        <file>iosup.c</file>
+                       <file>largepag.c</file>
                        <file>mdlsup.c</file>
                        <file>mminit.c</file>
                        <file>mmsup.c</file>
index 5016dbd..1297366 100644 (file)
@@ -1,5 +1,10 @@
 #include <msvctarget.h>
 #undef i386
+#ifndef __x86_64__
+#define FASTCALL fastcall
+#else
+#define FASTCALL stdcall
+#endif
 
 @ stdcall CcCanIWrite(ptr long long long)
 @ stdcall CcCopyRead(ptr ptr long long ptr ptr)
 @ stdcall DbgQueryDebugFilterState(long long)
 @ stdcall DbgSetDebugFilterState(long long long)
 @ stdcall -arch=x86_64 ExAcquireFastMutex(ptr)
-@ fastcall ExAcquireFastMutexUnsafe(ptr)
+@ FASTCALL ExAcquireFastMutexUnsafe(ptr)
 @ stdcall ExAcquireResourceExclusiveLite(ptr long)
 @ stdcall ExAcquireResourceSharedLite(ptr long)
-@ fastcall ExAcquireRundownProtection(ptr) ExfAcquireRundownProtection
-@ fastcall ExAcquireRundownProtectionCacheAware(ptr) ExfAcquireRundownProtectionCacheAware
-@ fastcall ExAcquireRundownProtectionCacheAwareEx(ptr long) ExfAcquireRundownProtectionCacheAwareEx
-@ fastcall ExAcquireRundownProtectionEx(ptr long) ExfAcquireRundownProtectionEx
+@ FASTCALL ExAcquireRundownProtection(ptr) ExfAcquireRundownProtection
+@ FASTCALL ExAcquireRundownProtectionCacheAware(ptr) ExfAcquireRundownProtectionCacheAware
+@ FASTCALL ExAcquireRundownProtectionCacheAwareEx(ptr long) ExfAcquireRundownProtectionCacheAwareEx
+@ FASTCALL ExAcquireRundownProtectionEx(ptr long) ExfAcquireRundownProtectionEx
 @ stdcall ExAcquireSharedStarveExclusive(ptr long)
 @ stdcall ExAcquireSharedWaitForExclusive(ptr long)
 @ stdcall ExAllocateCacheAwareRundownProtection(long long)
@@ -80,7 +85,7 @@
 @ stdcall ExDeleteResourceLite(ptr)
 @ extern ExDesktopObjectType
 @ stdcall ExDisableResourceBoostLite(ptr)
-@ fastcall ExEnterCriticalRegionAndAcquireFastMutexUnsafe(ptr)
+@ FASTCALL ExEnterCriticalRegionAndAcquireFastMutexUnsafe(ptr)
 @ stdcall ExEnterCriticalRegionAndAcquireResourceExclusive(ptr)
 @ stdcall ExEnterCriticalRegionAndAcquireResourceShared(ptr)
 @ stdcall ExEnterCriticalRegionAndAcquireSharedWaitForExclusive(ptr)
 @ stdcall ExInitializeNPagedLookasideList(ptr ptr ptr long long long long)
 @ stdcall ExInitializePagedLookasideList(ptr ptr ptr long long long long)
 @ stdcall ExInitializeResourceLite(ptr)
-@ fastcall ExInitializeRundownProtection(ptr) ExfInitializeRundownProtection
+@ FASTCALL ExInitializeRundownProtection(ptr) ExfInitializeRundownProtection
 @ stdcall ExInitializeRundownProtectionCacheAware(ptr long)
 @ stdcall ExInitializeZone(ptr long ptr long)
 @ stdcall ExInterlockedAddLargeInteger(ptr long long ptr)
 #ifndef __x86_64__
-@ fastcall ExInterlockedAddLargeStatistic(ptr long)
+@ FASTCALL ExInterlockedAddLargeStatistic(ptr long)
 #endif
 @ stdcall ExInterlockedAddUlong(ptr long ptr)
 #ifndef __x86_64__
-@ fastcall ExInterlockedCompareExchange64(ptr ptr ptr ptr)
+@ FASTCALL ExInterlockedCompareExchange64(ptr ptr ptr ptr)
 @ stdcall ExInterlockedDecrementLong(ptr ptr)
 @ stdcall ExInterlockedExchangeUlong(ptr long ptr)
 #endif
 @ stdcall ExInterlockedExtendZone(ptr ptr long ptr)
 #ifndef __x86_64__
-@ fastcall ExInterlockedFlushSList(ptr)
+@ FASTCALL ExInterlockedFlushSList(ptr)
 @ stdcall ExInterlockedIncrementLong(ptr ptr)
 #endif
 @ stdcall ExInterlockedInsertHeadList(ptr ptr ptr)
 @ stdcall ExInterlockedInsertTailList(ptr ptr ptr)
 @ stdcall ExInterlockedPopEntryList(ptr ptr)
 #ifndef __x86_64__
-@ fastcall ExInterlockedPopEntrySList(ptr ptr)
+@ FASTCALL ExInterlockedPopEntrySList(ptr ptr)
 #endif
 @ stdcall ExInterlockedPushEntryList(ptr ptr ptr)
 #ifndef __x86_64__
-@ fastcall ExInterlockedPushEntrySList(ptr ptr ptr)
+@ FASTCALL ExInterlockedPushEntrySList(ptr ptr ptr)
 #endif
 @ stdcall ExInterlockedRemoveHeadList(ptr ptr)
 @ stdcall ExIsProcessorFeaturePresent(long)
 @ stdcall ExRaiseException(ptr) RtlRaiseException
 @ stdcall ExRaiseHardError(long long long ptr long ptr)
 @ stdcall ExRaiseStatus(long) RtlRaiseStatus
-@ fastcall ExReInitializeRundownProtection(ptr) ExfReInitializeRundownProtection
-@ fastcall ExReInitializeRundownProtectionCacheAware(ptr) ExfReInitializeRundownProtectionCacheAware
+@ FASTCALL ExReInitializeRundownProtection(ptr) ExfReInitializeRundownProtection
+@ FASTCALL ExReInitializeRundownProtectionCacheAware(ptr) ExfReInitializeRundownProtectionCacheAware
 @ stdcall ExRegisterCallback(ptr ptr ptr)
 @ stdcall ExReinitializeResourceLite(ptr)
 @ stdcall -arch=x86_64 ExReleaseFastMutex(ptr)
-@ fastcall ExReleaseFastMutexUnsafe(ptr)
-@ fastcall ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(ptr)
-@ fastcall ExReleaseResourceAndLeaveCriticalRegion(ptr)
+@ FASTCALL ExReleaseFastMutexUnsafe(ptr)
+@ FASTCALL ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(ptr)
+@ FASTCALL ExReleaseResourceAndLeaveCriticalRegion(ptr)
 @ stdcall ExReleaseResourceForThreadLite(ptr long)
-@ fastcall ExReleaseResourceLite(ptr)
-@ fastcall ExReleaseRundownProtection(ptr) ExfReleaseRundownProtection
-@ fastcall ExReleaseRundownProtectionCacheAware(ptr) ExfReleaseRundownProtectionCacheAware
-@ fastcall ExReleaseRundownProtectionCacheAwareEx(ptr long) ExfReleaseRundownProtectionCacheAwareEx
-@ fastcall ExReleaseRundownProtectionEx(ptr long) ExfReleaseRundownProtectionEx
-@ fastcall ExRundownCompleted(ptr) ExfRundownCompleted
-@ fastcall ExRundownCompletedCacheAware(ptr) ExfRundownCompletedCacheAware
+@ FASTCALL ExReleaseResourceLite(ptr)
+@ FASTCALL ExReleaseRundownProtection(ptr) ExfReleaseRundownProtection
+@ FASTCALL ExReleaseRundownProtectionCacheAware(ptr) ExfReleaseRundownProtectionCacheAware
+@ FASTCALL ExReleaseRundownProtectionCacheAwareEx(ptr long) ExfReleaseRundownProtectionCacheAwareEx
+@ FASTCALL ExReleaseRundownProtectionEx(ptr long) ExfReleaseRundownProtectionEx
+@ FASTCALL ExRundownCompleted(ptr) ExfRundownCompleted
+@ FASTCALL ExRundownCompletedCacheAware(ptr) ExfRundownCompletedCacheAware
 @ extern ExSemaphoreObjectType _ExSemaphoreObjectType
 @ stdcall ExSetResourceOwnerPointer(ptr ptr)
 @ stdcall ExSetTimerResolution(long long)
 @ stdcall ExUnregisterCallback(ptr)
 @ stdcall ExUuidCreate(ptr)
 @ stdcall ExVerifySuite(long)
-@ fastcall ExWaitForRundownProtectionRelease(ptr) ExfWaitForRundownProtectionRelease
-@ fastcall ExWaitForRundownProtectionReleaseCacheAware(ptr) ExfWaitForRundownProtectionReleaseCacheAware
+@ FASTCALL ExWaitForRundownProtectionRelease(ptr) ExfWaitForRundownProtectionRelease
+@ FASTCALL ExWaitForRundownProtectionReleaseCacheAware(ptr) ExfWaitForRundownProtectionReleaseCacheAware
 @ extern ExWindowStationObjectType
-@ fastcall ExfAcquirePushLockExclusive(ptr)
-@ fastcall ExfAcquirePushLockShared(ptr)
+@ FASTCALL ExfAcquirePushLockExclusive(ptr)
+@ FASTCALL ExfAcquirePushLockShared(ptr)
 #ifndef __x86_64__
-@ fastcall ExfInterlockedAddUlong(ptr long ptr)
-@ fastcall ExfInterlockedCompareExchange64(ptr ptr ptr)
-@ fastcall ExfInterlockedInsertHeadList(ptr ptr ptr)
-@ fastcall ExfInterlockedInsertTailList(ptr ptr ptr)
-@ fastcall ExfInterlockedPopEntryList(ptr ptr)
-@ fastcall ExfInterlockedPushEntryList(ptr ptr ptr)
-@ fastcall ExfInterlockedRemoveHeadList(ptr ptr)
+@ FASTCALL ExfInterlockedAddUlong(ptr long ptr)
+@ FASTCALL ExfInterlockedCompareExchange64(ptr ptr ptr)
+@ FASTCALL ExfInterlockedInsertHeadList(ptr ptr ptr)
+@ FASTCALL ExfInterlockedInsertTailList(ptr ptr ptr)
+@ FASTCALL ExfInterlockedPopEntryList(ptr ptr)
+@ FASTCALL ExfInterlockedPushEntryList(ptr ptr ptr)
+@ FASTCALL ExfInterlockedRemoveHeadList(ptr ptr)
 #endif
-@ fastcall ExfReleasePushLock(ptr)
-@ fastcall ExfReleasePushLockExclusive(ptr)
-@ fastcall ExfReleasePushLockShared(ptr)
-@ fastcall ExfTryToWakePushLock(ptr)
-@ fastcall ExfUnblockPushLock(ptr ptr)
+@ FASTCALL ExfReleasePushLock(ptr)
+@ FASTCALL ExfReleasePushLockExclusive(ptr)
+@ FASTCALL ExfReleasePushLockShared(ptr)
+@ FASTCALL ExfTryToWakePushLock(ptr)
+@ FASTCALL ExfUnblockPushLock(ptr ptr)
 @ stdcall -arch=x86_64 ExpInterlockedFlushSList(ptr)
 @ stdcall -arch=x86_64 ExpInterlockedPopEntrySList(ptr ptr)
 @ stdcall -arch=x86_64 ExpInterlockedPushEntrySList(ptr ptr)
-@ fastcall -arch=i386 Exfi386InterlockedDecrementLong(ptr)
-@ fastcall -arch=i386 Exfi386InterlockedExchangeUlong(ptr long)
-@ fastcall -arch=i386 Exfi386InterlockedIncrementLong(ptr)
+@ FASTCALL -arch=i386 Exfi386InterlockedDecrementLong(ptr)
+@ FASTCALL -arch=i386 Exfi386InterlockedExchangeUlong(ptr long)
+@ FASTCALL -arch=i386 Exfi386InterlockedIncrementLong(ptr)
 @ stdcall -arch=i386 Exi386InterlockedDecrementLong(ptr)
 @ stdcall -arch=i386 Exi386InterlockedExchangeUlong(ptr long long)
 @ stdcall -arch=i386 Exi386InterlockedIncrementLong(ptr)
-@ fastcall -arch=i386 ExiAcquireFastMutex(ptr) ExAcquireFastMutex
-@ fastcall -arch=i386 ExiReleaseFastMutex(ptr) ExReleaseFastMutex
-@ fastcall -arch=i386 ExiTryToAcquireFastMutex(ptr) ExTryToAcquireFastMutex
+@ FASTCALL -arch=i386 ExiAcquireFastMutex(ptr) ExAcquireFastMutex
+@ FASTCALL -arch=i386 ExiReleaseFastMutex(ptr) ExReleaseFastMutex
+@ FASTCALL -arch=i386 ExiTryToAcquireFastMutex(ptr) ExTryToAcquireFastMutex
 @ stdcall FsRtlAcquireFileExclusive(ptr)
 ;FsRtlAddBaseMcbEntry
 @ stdcall FsRtlAddLargeMcbEntry(ptr long long long long long long)
 @ stdcall FsRtlUninitializeMcb(ptr)
 @ stdcall FsRtlUninitializeOplock(ptr)
 @ extern HalDispatchTable _HalDispatchTable
-@ fastcall HalExamineMBR(ptr long long ptr)
+@ FASTCALL HalExamineMBR(ptr long long ptr)
 @ extern HalPrivateDispatchTable
 ;HeadlessDispatch
 @ stdcall InbvAcquireDisplayOwnership()
 @ stdcall InbvSolidColorFill(long long long long long)
 @ extern InitSafeBootMode
 #ifndef __x86_64__
-@ fastcall InterlockedCompareExchange(ptr long long)
-@ fastcall InterlockedDecrement(ptr)
-@ fastcall InterlockedExchange(ptr long)
-@ fastcall InterlockedExchangeAdd(ptr long)
-@ fastcall InterlockedIncrement(ptr)
-@ fastcall InterlockedPopEntrySList(ptr)
-@ fastcall InterlockedPushEntrySList(ptr ptr)
+@ FASTCALL InterlockedCompareExchange(ptr long long)
+@ FASTCALL InterlockedDecrement(ptr)
+@ FASTCALL InterlockedExchange(ptr long)
+@ FASTCALL InterlockedExchangeAdd(ptr long)
+@ FASTCALL InterlockedIncrement(ptr)
+@ FASTCALL InterlockedPopEntrySList(ptr)
+@ FASTCALL InterlockedPushEntrySList(ptr ptr)
 #else
 @ stdcall InitializeSListHead(ptr) RtlInitializeSListHead
 #endif
 @ stdcall IoAllocateIrp(long long)
 @ stdcall IoAllocateMdl(ptr long long long ptr)
 @ stdcall IoAllocateWorkItem(ptr)
-@ fastcall IoAssignDriveLetters(ptr ptr ptr ptr)
+@ FASTCALL IoAssignDriveLetters(ptr ptr ptr ptr)
 @ stdcall IoAssignResources(ptr ptr ptr ptr ptr ptr)
 @ stdcall IoAttachDevice(ptr ptr ptr)
 @ stdcall IoAttachDeviceByPointer(ptr ptr)
 @ stdcall IoGetFileObjectGenericMapping()
 @ stdcall IoGetInitialStack()
 @ stdcall IoGetLowerDeviceObject(ptr)
-@ fastcall IoGetPagingIoPriority(ptr)
+@ FASTCALL IoGetPagingIoPriority(ptr)
 @ stdcall IoGetRelatedDeviceObject(ptr)
 @ stdcall IoGetRequestorProcess(ptr)
 @ stdcall IoGetRequestorProcessId(ptr)
 @ stdcall IoRaiseInformationalHardError(long ptr ptr)
 @ stdcall IoReadDiskSignature(ptr long ptr)
 @ extern IoReadOperationCount
-@ fastcall IoReadPartitionTable(ptr long long ptr)
+@ FASTCALL IoReadPartitionTable(ptr long long ptr)
 @ stdcall IoReadPartitionTableEx(ptr ptr)
 @ extern IoReadTransferCount
 @ stdcall IoRegisterBootDriverReinitialization(ptr ptr ptr)
 @ stdcall IoSetHardErrorOrVerifyDevice(ptr ptr)
 @ stdcall IoSetInformation(ptr ptr long ptr)
 @ stdcall IoSetIoCompletion(ptr ptr ptr long ptr long)
-@ fastcall IoSetPartitionInformation(ptr long long long)
+@ FASTCALL IoSetPartitionInformation(ptr long long long)
 @ stdcall IoSetPartitionInformationEx(ptr long ptr)
 @ stdcall IoSetShareAccess(long long ptr ptr)
 @ stdcall IoSetStartIoAttributes(ptr long long)
 @ stdcall IoWMIWriteEvent(ptr)
 @ stdcall IoWriteErrorLogEntry(ptr)
 @ extern IoWriteOperationCount
-@ fastcall IoWritePartitionTable(ptr long long long ptr)
+@ FASTCALL IoWritePartitionTable(ptr long long long ptr)
 @ stdcall IoWritePartitionTableEx(ptr ptr)
 @ extern IoWriteTransferCount
-@ fastcall IofCallDriver(ptr ptr)
-@ fastcall IofCompleteRequest(ptr long)
+@ FASTCALL IofCallDriver(ptr ptr)
+@ FASTCALL IofCompleteRequest(ptr long)
 @ stdcall KdChangeOption(long long ptr long ptr ptr)
 @ extern KdDebuggerEnabled _KdDebuggerEnabled
 @ extern KdDebuggerNotPresent _KdDebuggerNotPresent
 @ stdcall -arch=i386 Ke386IoSetAccessProcess(ptr long)
 @ stdcall -arch=i386 Ke386QueryIoAccessMap(long ptr)
 @ stdcall -arch=i386 Ke386SetIoAccessMap(long ptr)
-@ fastcall KeAcquireGuardedMutex(ptr)
-@ fastcall KeAcquireGuardedMutexUnsafe(ptr)
-@ fastcall KeAcquireInStackQueuedSpinLockAtDpcLevel(ptr ptr)
-@ fastcall KeAcquireInStackQueuedSpinLockForDpc(ptr ptr)
+@ FASTCALL KeAcquireGuardedMutex(ptr)
+@ FASTCALL KeAcquireGuardedMutexUnsafe(ptr)
+@ FASTCALL KeAcquireInStackQueuedSpinLockAtDpcLevel(ptr ptr)
+@ FASTCALL KeAcquireInStackQueuedSpinLockForDpc(ptr ptr)
 @ stdcall KeAcquireInterruptSpinLock(ptr)
 @ stdcall KeAcquireSpinLockAtDpcLevel(ptr)
-@ fastcall KeAcquireSpinLockForDpc(ptr)
+@ FASTCALL KeAcquireSpinLockForDpc(ptr)
 @ stdcall -arch=x86_64 KeAcquireSpinLockRaiseToDpc(ptr)
 @ stdcall KeAddSystemServiceTable(ptr ptr long ptr long)
 @ stdcall KeAreAllApcsDisabled()
 @ stdcall KeInitializeDeviceQueue(ptr)
 @ stdcall KeInitializeDpc(ptr ptr ptr)
 @ stdcall KeInitializeEvent(ptr long long)
-@ fastcall KeInitializeGuardedMutex(ptr)
+@ FASTCALL KeInitializeGuardedMutex(ptr)
 @ stdcall KeInitializeInterrupt(ptr ptr ptr ptr long long long long long long long)
 @ stdcall KeInitializeMutant(ptr long)
 @ stdcall KeInitializeMutex(ptr long)
 @ stdcall KeRegisterBugCheckCallback(ptr ptr ptr long ptr)
 @ stdcall KeRegisterBugCheckReasonCallback(ptr ptr ptr ptr)
 @ stdcall KeRegisterNmiCallback(ptr ptr)
-@ fastcall KeReleaseGuardedMutex(ptr)
-@ fastcall KeReleaseGuardedMutexUnsafe(ptr)
-@ fastcall KeReleaseInStackQueuedSpinLockForDpc(ptr)
-@ fastcall KeReleaseInStackQueuedSpinLockFromDpcLevel(ptr)
+@ FASTCALL KeReleaseGuardedMutex(ptr)
+@ FASTCALL KeReleaseGuardedMutexUnsafe(ptr)
+@ FASTCALL KeReleaseInStackQueuedSpinLockForDpc(ptr)
+@ FASTCALL KeReleaseInStackQueuedSpinLockFromDpcLevel(ptr)
 @ stdcall KeReleaseInterruptSpinLock(ptr long)
 @ stdcall KeReleaseMutant(ptr long long long)
 @ stdcall KeReleaseMutex(ptr long)
 #ifdef __x86_64__
 @ stdcall KeReleaseSpinLock(ptr long)
 #endif
-@ fastcall KeReleaseSpinLockForDpc(ptr long)
+@ FASTCALL KeReleaseSpinLockForDpc(ptr long)
 @ stdcall KeReleaseSpinLockFromDpcLevel(ptr)
 @ stdcall KeRemoveByKeyDeviceQueue(ptr long)
 @ stdcall KeRemoveByKeyDeviceQueueIfBusy(ptr long)
 @ stdcall KeStackAttachProcess(ptr ptr)
 @ stdcall KeSynchronizeExecution(ptr ptr ptr)
 @ stdcall KeTerminateThread(long)
-@ fastcall KeTestSpinLock(ptr)
+@ FASTCALL KeTestSpinLock(ptr)
 @ extern KeTickCount
-@ fastcall KeTryToAcquireGuardedMutex(ptr)
-@ fastcall KeTryToAcquireSpinLockAtDpcLevel(ptr)
+@ FASTCALL KeTryToAcquireGuardedMutex(ptr)
+@ FASTCALL KeTryToAcquireSpinLockAtDpcLevel(ptr)
 @ stdcall KeUnstackDetachProcess(ptr)
 @ stdcall KeUpdateRunTime(ptr long)
 @ fastcall KeUpdateSystemTime(ptr long long)
 @ stdcall KeWaitForMultipleObjects(long ptr long long long long ptr ptr)
 @ stdcall KeWaitForMutexObject(ptr long long long ptr) KeWaitForSingleObject
 @ stdcall KeWaitForSingleObject(ptr long long long ptr)
-@ fastcall KefAcquireSpinLockAtDpcLevel(ptr)
-@ fastcall KefReleaseSpinLockFromDpcLevel(ptr)
+@ FASTCALL KefAcquireSpinLockAtDpcLevel(ptr)
+@ FASTCALL KefReleaseSpinLockFromDpcLevel(ptr)
 @ stdcall -arch=i386 Kei386EoiHelper()
 @ fastcall -arch=i386 KiEoiHelper(ptr) /* FIXME: Evaluate decision */
-@ fastcall KiAcquireSpinLock(ptr)
+@ FASTCALL KiAcquireSpinLock(ptr)
 @ extern KiBugCheckData
 @ stdcall KiCheckForKernelApcDelivery()
 ;KiCheckForSListAddress
 @ stdcall -arch=i386 KiDispatchInterrupt()
 @ extern KiEnableTimerWatchdog
 @ stdcall KiIpiServiceRoutine(ptr ptr)
-@ fastcall KiReleaseSpinLock(ptr)
+@ FASTCALL KiReleaseSpinLock(ptr)
 @ cdecl KiUnexpectedInterrupt()
 #ifdef _M_IX86
 @ stdcall Kii386SpinOnSpinLock(ptr long)
 ;ObSetHandleAttributes@12
 @ stdcall ObSetSecurityDescriptorInfo(ptr ptr ptr ptr long ptr)
 @ stdcall ObSetSecurityObjectByPointer(ptr long ptr)
-@ fastcall ObfDereferenceObject(ptr)
-@ fastcall ObfReferenceObject(ptr)
+@ FASTCALL ObfDereferenceObject(ptr)
+@ FASTCALL ObfReferenceObject(ptr)
 ;PfxFindPrefix
 ;PfxInitialize
 ;PfxInsertPrefix
 @ stdcall RtlOemStringToUnicodeString(ptr ptr long)
 @ stdcall RtlOemToUnicodeN(wstr long ptr ptr long)
 @ stdcall RtlPinAtomInAtomTable(ptr ptr)
-@ fastcall RtlPrefetchMemoryNonTemporal(ptr long)
+@ FASTCALL RtlPrefetchMemoryNonTemporal(ptr long)
 @ stdcall RtlPrefixString(ptr ptr long)
 @ stdcall RtlPrefixUnicodeString(ptr ptr long)
 @ stdcall RtlQueryAtomInAtomTable(ptr ptr ptr ptr ptr ptr)
 ;RtlTraceDatabaseUnlock
 ;RtlTraceDatabaseValidate
 #ifndef __x86_64__
-@ fastcall RtlUlongByteSwap(long)
-@ fastcall RtlUlonglongByteSwap(long long)
+@ FASTCALL RtlUlongByteSwap(long)
+@ FASTCALL RtlUlonglongByteSwap(long long)
 #endif
 @ stdcall RtlUnicodeStringToAnsiSize(ptr) RtlxUnicodeStringToAnsiSize
 @ stdcall RtlUnicodeStringToAnsiString(ptr ptr long)
 @ stdcall RtlUpperChar(long)
 @ stdcall RtlUpperString(ptr ptr)
 #ifndef __x86_64__
-@ fastcall RtlUshortByteSwap(long)
+@ FASTCALL RtlUshortByteSwap(long)
 #endif
 @ stdcall RtlValidRelativeSecurityDescriptor(ptr long long)
 @ stdcall RtlValidSecurityDescriptor(ptr)
index 27f7895..4a6c8bc 100644 (file)
@@ -317,7 +317,7 @@ RtlWalkFrameChain(OUT PVOID *Callers,
                                         &StackBegin,
                                         &StackEnd);
         if (!Result) return 0;
-    }
+        }
 
     /* Use a SEH block for maximum protection */
     _SEH2_TRY
@@ -331,12 +331,11 @@ RtlWalkFrameChain(OUT PVOID *Callers,
 
             /* Make sure we can trust the TEB and trap frame */
             if (!(Teb) ||
-                !(Thread->SystemThread) ||
                 (KeIsAttachedProcess()) ||
                 (KeGetCurrentIrql() >= DISPATCH_LEVEL))
             {
                 /* Invalid or unsafe attempt to get the stack */
-                return 0;
+                _SEH2_YIELD(return 0;)
             }
 
             /* Get the stack limits */
index d06fb04..de37447 100644 (file)
@@ -314,6 +314,31 @@ SepSidInToken(PACCESS_TOKEN _Token,
     return FALSE;
 }
 
+static BOOLEAN
+SepTokenIsOwner(PACCESS_TOKEN Token,
+                PSECURITY_DESCRIPTOR SecurityDescriptor)
+{
+    NTSTATUS Status;
+    PSID Sid = NULL;
+    BOOLEAN Defaulted;
+
+    Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
+                                           &Sid,
+                                           &Defaulted);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
+        return FALSE;
+    }
+
+    if (Sid == NULL)
+    {
+        DPRINT1("Owner Sid is NULL\n");
+        return FALSE;
+    }
+
+    return SepSidInToken(Token, Sid);
+}
 
 VOID NTAPI
 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
@@ -352,6 +377,9 @@ SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
     }
 }
 
+
+#define OLD_ACCESS_CHECK
+
 BOOLEAN NTAPI
 SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
                IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
@@ -364,7 +392,13 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
                OUT PNTSTATUS AccessStatus)
 {
     LUID_AND_ATTRIBUTES Privilege;
+#ifdef OLD_ACCESS_CHECK
     ACCESS_MASK CurrentAccess, AccessMask;
+#endif
+    ACCESS_MASK RemainingAccess;
+    ACCESS_MASK TempAccess;
+    ACCESS_MASK TempGrantedAccess = 0;
+    ACCESS_MASK TempDeniedAccess = 0;
     PACCESS_TOKEN Token;
     ULONG i;
     PACL Dacl;
@@ -398,15 +432,45 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
     if (PreviouslyGrantedAccess)
         RtlMapGenericMask(&PreviouslyGrantedAccess, GenericMapping);
 
-
-
+#ifdef OLD_ACCESS_CHECK
     CurrentAccess = PreviouslyGrantedAccess;
-
-
+#endif
+    /* Initialize remaining access rights */
+    RemainingAccess = DesiredAccess;
 
     Token = SubjectSecurityContext->ClientToken ?
     SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
 
+    /* Check for system security access */
+    if (RemainingAccess & ACCESS_SYSTEM_SECURITY)
+    {
+        Privilege.Luid = SeSecurityPrivilege;
+        Privilege.Attributes = SE_PRIVILEGE_ENABLED;
+
+        /* Fail if we do not the SeSecurityPrivilege */
+        if (!SepPrivilegeCheck(Token,
+                               &Privilege,
+                               1,
+                               PRIVILEGE_SET_ALL_NECESSARY,
+                               AccessMode))
+        {
+            *AccessStatus = STATUS_PRIVILEGE_NOT_HELD;
+            return FALSE;
+        }
+
+        /* Adjust access rights */
+        RemainingAccess &= ~ACCESS_SYSTEM_SECURITY;
+        PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY;
+
+        /* Succeed if there are no more rights to grant */
+        if (RemainingAccess == 0)
+        {
+            *GrantedAccess = PreviouslyGrantedAccess;
+            *AccessStatus = STATUS_SUCCESS;
+            return TRUE;
+        }
+    }
+
     /* Get the DACL */
     Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
                                           &Present,
@@ -435,57 +499,54 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
         return TRUE;
     }
 
+#ifdef OLD_ACCESS_CHECK
     CurrentAccess = PreviouslyGrantedAccess;
+#endif
 
     /* RULE 2: Check token for 'take ownership' privilege */
-    Privilege.Luid = SeTakeOwnershipPrivilege;
-    Privilege.Attributes = SE_PRIVILEGE_ENABLED;
-
-    if (SepPrivilegeCheck(Token,
-                          &Privilege,
-                          1,
-                          PRIVILEGE_SET_ALL_NECESSARY,
-                          AccessMode))
-    {
-        CurrentAccess |= WRITE_OWNER;
-        if ((DesiredAccess & ~VALID_INHERIT_FLAGS) == 
-            (CurrentAccess & ~VALID_INHERIT_FLAGS))
+    if (DesiredAccess & WRITE_OWNER)
+    {
+        Privilege.Luid = SeTakeOwnershipPrivilege;
+        Privilege.Attributes = SE_PRIVILEGE_ENABLED;
+
+        if (SepPrivilegeCheck(Token,
+                              &Privilege,
+                              1,
+                              PRIVILEGE_SET_ALL_NECESSARY,
+                              AccessMode))
         {
-            *GrantedAccess = CurrentAccess;
-            *AccessStatus = STATUS_SUCCESS;
-            return TRUE;
+            /* Adjust access rights */
+            RemainingAccess &= ~WRITE_OWNER;
+            PreviouslyGrantedAccess |= WRITE_OWNER;
+#ifdef OLD_ACCESS_CHECK
+            CurrentAccess |= WRITE_OWNER;
+#endif
+
+            /* Succeed if there are no more rights to grant */
+            if (RemainingAccess == 0)
+            {
+                *GrantedAccess = PreviouslyGrantedAccess;
+                *AccessStatus = STATUS_SUCCESS;
+                return TRUE;
+            }
         }
     }
 
     /* Deny access if the DACL is empty */
     if (Dacl->AceCount == 0)
     {
-        *GrantedAccess = 0;
-        *AccessStatus = STATUS_ACCESS_DENIED;
-        return FALSE;
-    }
-
-    /* RULE 3: Check whether the token is the owner */
-    Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
-                                           &Sid,
-                                           &Defaulted);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
-        *AccessStatus = Status;
-        return FALSE;
-    }
-
-    if (Sid && SepSidInToken(Token, Sid))
-    {
-        CurrentAccess |= (READ_CONTROL | WRITE_DAC);
-        if ((DesiredAccess & ~VALID_INHERIT_FLAGS) == 
-            (CurrentAccess & ~VALID_INHERIT_FLAGS))
+        if (RemainingAccess == MAXIMUM_ALLOWED && PreviouslyGrantedAccess != 0)
         {
-            *GrantedAccess = CurrentAccess;
+            *GrantedAccess = PreviouslyGrantedAccess;
             *AccessStatus = STATUS_SUCCESS;
             return TRUE;
         }
+        else
+        {
+            *GrantedAccess = 0;
+            *AccessStatus = STATUS_ACCESS_DENIED;
+            return FALSE;
+        }
     }
 
     /* Fail if DACL is absent */
@@ -496,50 +557,134 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
         return FALSE;
     }
 
-    /* RULE 4: Grant rights according to the DACL */
-    CurrentAce = (PACE)(Dacl + 1);
-    for (i = 0; i < Dacl->AceCount; i++)
+    /* Determine the MAXIMUM_ALLOWED access rights according to the DACL */
+    if (DesiredAccess & MAXIMUM_ALLOWED)
     {
-        Sid = (PSID)(CurrentAce + 1);
-        if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
+        CurrentAce = (PACE)(Dacl + 1);
+        for (i = 0; i < Dacl->AceCount; i++)
         {
-            if (SepSidInToken(Token, Sid))
+            if (!(CurrentAce->Header.AceFlags & INHERIT_ONLY_ACE))
             {
-                *GrantedAccess = 0;
-                *AccessStatus = STATUS_ACCESS_DENIED;
-                return FALSE;
+                Sid = (PSID)(CurrentAce + 1);
+                if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
+                {
+                    if (SepSidInToken(Token, Sid))
+                    {
+                        /* Map access rights from the ACE */
+                        TempAccess = CurrentAce->AccessMask;
+                        RtlMapGenericMask(&TempAccess, GenericMapping);
+
+                        /* Deny access rights that have not been granted yet */
+                        TempDeniedAccess |= (TempAccess & ~TempGrantedAccess);
+                    }
+                }
+                else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
+                {
+                    if (SepSidInToken(Token, Sid))
+                    {
+                        /* Map access rights from the ACE */
+                        TempAccess = CurrentAce->AccessMask;
+                        RtlMapGenericMask(&TempAccess, GenericMapping);
+
+                        /* Grant access rights that have not been denied yet */
+                        TempGrantedAccess |= (TempAccess & ~TempDeniedAccess);
+                    }
+                }
+                else
+                {
+                    DPRINT1("Unsupported ACE type 0x%lx\n", CurrentAce->Header.AceType);
+                }
             }
+
+            /* Get the next ACE */
+            CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize);
         }
 
-        else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
+        /* Fail if some rights have not been granted */
+        RemainingAccess &= ~(MAXIMUM_ALLOWED | TempGrantedAccess);
+        if (RemainingAccess != 0)
         {
-            if (SepSidInToken(Token, Sid))
-            {
-                AccessMask = CurrentAce->AccessMask;
-                RtlMapGenericMask(&AccessMask, GenericMapping);
-                CurrentAccess |= AccessMask;
-            }
+            *GrantedAccess = 0;
+            *AccessStatus = STATUS_ACCESS_DENIED;
+            return FALSE;
+        }
+
+        /* Set granted access right and access status */
+        *GrantedAccess = TempGrantedAccess | PreviouslyGrantedAccess;
+        if (*GrantedAccess != 0)
+        {
+            *AccessStatus = STATUS_SUCCESS;
+            return TRUE;
         }
         else
         {
-            DPRINT1("Unknown Ace type 0x%lx\n", CurrentAce->Header.AceType);
+            *AccessStatus = STATUS_ACCESS_DENIED;
+            return FALSE;
+        }
+    }
+
+    /* RULE 4: Grant rights according to the DACL */
+    CurrentAce = (PACE)(Dacl + 1);
+    for (i = 0; i < Dacl->AceCount; i++)
+    {
+        if (!(CurrentAce->Header.AceFlags & INHERIT_ONLY_ACE))
+        {
+            Sid = (PSID)(CurrentAce + 1);
+            if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
+            {
+                if (SepSidInToken(Token, Sid))
+                {
+#ifdef OLD_ACCESS_CHECK
+                    *GrantedAccess = 0;
+                    *AccessStatus = STATUS_ACCESS_DENIED;
+                    return FALSE;
+#else
+                    /* Map access rights from the ACE */
+                    TempAccess = CurrentAce->AccessMask;
+                    RtlMapGenericMask(&TempAccess, GenericMapping);
+
+                    /* Leave if a remaining right must be denied */
+                    if (RemainingAccess & TempAccess)
+                        break;
+#endif
+                }
+            }
+            else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
+            {
+                if (SepSidInToken(Token, Sid))
+                {
+#ifdef OLD_ACCESS_CHECK
+                    AccessMask = CurrentAce->AccessMask;
+                    RtlMapGenericMask(&AccessMask, GenericMapping);
+                    CurrentAccess |= AccessMask;
+#else
+                    /* Map access rights from the ACE */
+                    TempAccess = CurrentAce->AccessMask;
+                    RtlMapGenericMask(&TempAccess, GenericMapping);
+
+                    /* Remove granted rights */
+                    RemainingAccess &= ~TempAccess;
+#endif
+                }
+            }
+            else
+            {
+                DPRINT1("Unsupported ACE type 0x%lx\n", CurrentAce->Header.AceType);
+            }
         }
+
+        /* Get the next ACE */
         CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize);
     }
 
+#ifdef OLD_ACCESS_CHECK
     DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
            CurrentAccess, DesiredAccess);
 
     *GrantedAccess = CurrentAccess & DesiredAccess;
 
-    if (DesiredAccess & MAXIMUM_ALLOWED)
-    {
-        *GrantedAccess = CurrentAccess;
-        *AccessStatus = STATUS_SUCCESS;
-        return TRUE;
-    }
-    else if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == 
-             (DesiredAccess & ~VALID_INHERIT_FLAGS))
+    if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == 
+        (DesiredAccess & ~VALID_INHERIT_FLAGS))
     {
         *AccessStatus = STATUS_SUCCESS;
         return TRUE;
@@ -553,6 +698,33 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
         *AccessStatus = STATUS_SUCCESS;
         return TRUE;
     }
+#else
+    DPRINT("DesiredAccess %08lx\nPreviouslyGrantedAccess %08lx\nRemainingAccess %08lx\n",
+           DesiredAccess, PreviouslyGrantedAccess, RemainingAccess);
+
+    /* Fail if some rights have not been granted */
+    if (RemainingAccess != 0)
+    {
+        *GrantedAccess = 0;
+        *AccessStatus = STATUS_ACCESS_DENIED;
+        return FALSE;
+    }
+
+    /* Set granted access rights */
+    *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess;
+
+    DPRINT("GrantedAccess %08lx\n", *GrantedAccess);
+
+    /* Fail if no rights have been granted */
+    if (*GrantedAccess == 0)
+    {
+        *AccessStatus = STATUS_ACCESS_DENIED;
+        return FALSE;
+    }
+
+    *AccessStatus = STATUS_SUCCESS;
+    return TRUE;
+#endif
 }
 
 static PSID
@@ -649,16 +821,43 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
     if (!SubjectContextLocked)
         SeLockSubjectContext(SubjectSecurityContext);
 
-    /* Call the internal function */
-    ret = SepAccessCheck(SecurityDescriptor,
-                         SubjectSecurityContext,
-                         DesiredAccess,
-                         PreviouslyGrantedAccess,
-                         Privileges,
-                         GenericMapping,
-                         AccessMode,
-                         GrantedAccess,
-                         AccessStatus);
+    /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
+    if (DesiredAccess & (WRITE_DAC | READ_CONTROL | MAXIMUM_ALLOWED))
+    {
+         PACCESS_TOKEN Token = SubjectSecurityContext->ClientToken ?
+             SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
+
+        if (SepTokenIsOwner(Token,
+                            SecurityDescriptor))
+        {
+            if (DesiredAccess & MAXIMUM_ALLOWED)
+                PreviouslyGrantedAccess |= (WRITE_DAC | READ_CONTROL);
+            else
+                PreviouslyGrantedAccess |= (DesiredAccess & (WRITE_DAC | READ_CONTROL));
+
+            DesiredAccess &= ~(WRITE_DAC | READ_CONTROL);
+        }
+    }
+
+    if (DesiredAccess == 0)
+    {
+        *GrantedAccess = PreviouslyGrantedAccess;
+        *AccessStatus = STATUS_SUCCESS;
+        ret = TRUE;
+    }
+    else
+    {
+        /* Call the internal function */
+        ret = SepAccessCheck(SecurityDescriptor,
+                             SubjectSecurityContext,
+                             DesiredAccess,
+                             PreviouslyGrantedAccess,
+                             Privileges,
+                             GenericMapping,
+                             AccessMode,
+                             GrantedAccess,
+                             AccessStatus);
+    }
 
     /* Release the lock if needed */
     if (!SubjectContextLocked)
@@ -686,6 +885,7 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
     PSECURITY_DESCRIPTOR CapturedSecurityDescriptor = NULL;
     SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    ACCESS_MASK PreviouslyGrantedAccess = 0;
     PTOKEN Token;
     NTSTATUS Status;
     PAGED_CODE();
@@ -801,16 +1001,38 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
     SubjectSecurityContext.ProcessAuditId = NULL;
     SeLockSubjectContext(&SubjectSecurityContext);
 
-    /* Now perform the access check */
-    SepAccessCheck(SecurityDescriptor, // FIXME: use CapturedSecurityDescriptor
-                   &SubjectSecurityContext,
-                   DesiredAccess,
-                   0,
-                   &PrivilegeSet, //FIXME
-                   GenericMapping,
-                   PreviousMode,
-                   GrantedAccess,
-                   AccessStatus);
+    /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
+    if (DesiredAccess & (WRITE_DAC | READ_CONTROL | MAXIMUM_ALLOWED))
+    {
+        if (SepTokenIsOwner(Token, SecurityDescriptor)) // FIXME: use CapturedSecurityDescriptor
+        {
+            if (DesiredAccess & MAXIMUM_ALLOWED)
+                PreviouslyGrantedAccess |= (WRITE_DAC | READ_CONTROL);
+            else
+                PreviouslyGrantedAccess |= (DesiredAccess & (WRITE_DAC | READ_CONTROL));
+
+            DesiredAccess &= ~(WRITE_DAC | READ_CONTROL);
+        }
+    }
+
+    if (DesiredAccess == 0)
+    {
+        *GrantedAccess = PreviouslyGrantedAccess;
+        *AccessStatus = STATUS_SUCCESS;
+    }
+    else
+    {
+        /* Now perform the access check */
+        SepAccessCheck(SecurityDescriptor, // FIXME: use CapturedSecurityDescriptor
+                       &SubjectSecurityContext,
+                       DesiredAccess,
+                       PreviouslyGrantedAccess,
+                       &PrivilegeSet, //FIXME
+                       GenericMapping,
+                       PreviousMode,
+                       GrantedAccess,
+                       AccessStatus);
+    }
 
     /* Unlock subject context */
     SeUnlockSubjectContext(&SubjectSecurityContext);
index 21f814b..c8f5a7c 100644 (file)
@@ -41,7 +41,7 @@ set "_ROSBE_FULL_PATH_=%_ROSBE_PATH_DIR%%_ROSBE_PATH_%"
 ::echo RosBE insall path = %_ROSBE_FULL_PATH_%
 
 :: Set the path which contains our build tools
-set _ROSBE_BIN_PATH=%_ROSBE_FULL_PATH_%i386\bin
+set _ROSBE_BIN_PATH=%_ROSBE_FULL_PATH_%Tools
 
 :: Add the path to the search path
 path=%path%;%_ROSBE_BIN_PATH%
index afa44ef..5a9a29a 100644 (file)
@@ -282,8 +282,8 @@ WinMain(HINSTANCE hInstance,  HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nSho
     WCHAR PromptMsg[RC_STRING_MAX_SIZE];
     CHAR InputBuffer[255];
 
-    LoadString( GetModuleHandle(NULL), STRING_WelcomeMsg,  (LPTSTR) WelcomeMsg,sizeof(WelcomeMsg) / sizeof(WelcomeMsg[0]));
-    LoadString( GetModuleHandle(NULL), STRING_PromptMsg,  (LPTSTR) PromptMsg ,sizeof(PromptMsg) / sizeof(PromptMsg[0]));
+    LoadStringW( GetModuleHandle(NULL), STRING_WelcomeMsg, WelcomeMsg,sizeof(WelcomeMsg) / sizeof(WelcomeMsg[0]));
+    LoadStringW( GetModuleHandle(NULL), STRING_PromptMsg, PromptMsg ,sizeof(PromptMsg) / sizeof(PromptMsg[0]));
 
     AllocConsole();
     SetConsoleTitleW(L"ntvdm");
index 2b3c6b7..e1fc421 100644 (file)
@@ -180,402 +180,6 @@ Win32CsrInitComplete(void)
   return TRUE;
 }
 
-static BOOL WINAPI
-Win32CsrHardError(IN PCSRSS_PROCESS_DATA ProcessData,
-                  IN PHARDERROR_MSG HardErrorMessage)
-{
-    UINT responce = MB_OK;
-    NTSTATUS Status;
-    HANDLE hProcess;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    ULONG nParam = 0;
-    PRTL_MESSAGE_RESOURCE_ENTRY MessageResource;
-    ULONG_PTR ParameterList[MAXIMUM_HARDERROR_PARAMETERS];
-    LPSTR CaptionText, MessageBody;
-    LPWSTR szxCaptionText, szxMessageBody;
-    DWORD SizeOfAllUnicodeStrings = 0;
-    PROCESS_BASIC_INFORMATION ClientBasicInfo;
-    UNICODE_STRING ClientFileNameU;
-    UNICODE_STRING TempStringU;
-    UNICODE_STRING ParameterStringU;
-    ANSI_STRING ParamStringA;
-    ULONG UnicodeStringParameterMask = HardErrorMessage->UnicodeStringParameterMask;
-    int MessageBoxResponse;
-
-    HardErrorMessage->Response = ResponseNotHandled;
-
-    DPRINT("NumberOfParameters = %d\n", HardErrorMessage->NumberOfParameters);
-    DPRINT("Status = %lx\n", HardErrorMessage->Status);
-
-    // open client process
-    InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
-    Status = NtOpenProcess(&hProcess, PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, &ObjectAttributes, &HardErrorMessage->h.ClientId);
-    if( !NT_SUCCESS(Status) ) {
-        DPRINT1("NtOpenProcess failed with code: %lx\n", Status);
-        return FALSE;
-    }
-
-    // let's get a name of the client process to display it in the caption of a message box
-
-    ClientFileNameU.MaximumLength = 0;
-    ClientFileNameU.Length = 0;
-    ClientFileNameU.Buffer = NULL;
-    Status = NtQueryInformationProcess(hProcess, 
-        ProcessBasicInformation, 
-        &ClientBasicInfo, 
-        sizeof(ClientBasicInfo), 
-        NULL);
-    if( NT_SUCCESS(Status) ) {
-        PLIST_ENTRY ModuleListHead;
-        PLIST_ENTRY Entry;
-        PLDR_DATA_TABLE_ENTRY Module;
-        PPEB_LDR_DATA Ldr;
-        PPEB Peb = ClientBasicInfo.PebBaseAddress;
-
-        if( Peb )
-        {
-            Status = NtReadVirtualMemory(hProcess, &Peb->Ldr, &Ldr, sizeof(Ldr), NULL);
-            if( NT_SUCCESS(Status) ) {
-                ModuleListHead = &Ldr->InLoadOrderModuleList;
-                Status = NtReadVirtualMemory(
-                    hProcess,
-                    &ModuleListHead->Flink,
-                    &Entry,
-                    sizeof(Entry),
-                    NULL
-                    );
-
-                if( NT_SUCCESS(Status) )
-                {
-                    if (Entry != ModuleListHead)
-                    {
-                        LDR_DATA_TABLE_ENTRY ModuleData;
-                        Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
-
-                        Status = NtReadVirtualMemory(hProcess, Module, &ModuleData, sizeof(ModuleData), NULL);
-                        if( NT_SUCCESS(Status) ) {
-                            PVOID ClientDllBase;
-
-                            Status = NtReadVirtualMemory(
-                                hProcess,
-                                &Peb->ImageBaseAddress,
-                                &ClientDllBase,
-                                sizeof(ClientDllBase),
-                                NULL
-                                );
-                            if( NT_SUCCESS(Status) && (ClientDllBase == ModuleData.DllBase) ) {
-
-                                ClientFileNameU.MaximumLength = ModuleData.BaseDllName.MaximumLength;
-                                ClientFileNameU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ClientFileNameU.MaximumLength);
-                                Status = NtReadVirtualMemory(
-                                    hProcess,
-                                    ModuleData.BaseDllName.Buffer,
-                                    ClientFileNameU.Buffer,
-                                    ClientFileNameU.MaximumLength,
-                                    NULL
-                                    );
-                                if( NT_SUCCESS(Status) ) {
-                                    ClientFileNameU.Length = wcslen(ClientFileNameU.Buffer)*sizeof(wchar_t);
-                                }
-                                else {
-                                    RtlFreeHeap (RtlGetProcessHeap(), 0, ClientFileNameU.Buffer);
-                                    ClientFileNameU.Buffer = NULL;
-                                }
-
-                                DPRINT("ClientFileNameU=\'%wZ\'\n", &ClientFileNameU);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    // read all unicode strings from client space
-    for(nParam = 0; nParam < HardErrorMessage->NumberOfParameters; nParam++, UnicodeStringParameterMask >>= 1)
-    {
-        if( UnicodeStringParameterMask & 0x01 ) {
-            Status = NtReadVirtualMemory(hProcess,
-                (PVOID)HardErrorMessage->Parameters[nParam],
-                (PVOID)&TempStringU, 
-                sizeof(TempStringU),
-                NULL);
-
-            if( NT_SUCCESS(Status) ) {
-                ParameterStringU.Buffer = (PWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, TempStringU.MaximumLength);
-                if( !ParameterStringU.Buffer ) {
-                    DPRINT1("Cannot allocate memory %d\n", TempStringU.MaximumLength);
-                    NtClose(hProcess);
-                    if( ClientFileNameU.Buffer ) {
-                        RtlFreeHeap (RtlGetProcessHeap(), 0, ClientFileNameU.Buffer);
-                    }
-                    return FALSE;
-                }
-
-                Status = NtReadVirtualMemory(hProcess,
-                    (PVOID)TempStringU.Buffer,
-                    (PVOID)ParameterStringU.Buffer,
-                    TempStringU.MaximumLength,
-                    NULL);
-                if( !NT_SUCCESS(Status) ) {
-                    DPRINT1("NtReadVirtualMemory failed with code: %lx\n", Status);
-                    RtlFreeHeap (RtlGetProcessHeap(), 0, ParameterStringU.Buffer);
-                    if( ClientFileNameU.Buffer ) {
-                        RtlFreeHeap (RtlGetProcessHeap(), 0, ClientFileNameU.Buffer);
-                    }
-                    NtClose(hProcess);
-                    return FALSE;
-                }
-                ParameterStringU.Length = TempStringU.Length;
-                ParameterStringU.MaximumLength = TempStringU.MaximumLength;
-                DPRINT("ParameterStringU=\'%wZ\'\n", &ParameterStringU);
-                RtlUnicodeStringToAnsiString(&ParamStringA, &ParameterStringU, TRUE);
-                ParameterList[nParam] = (ULONG_PTR)ParamStringA.Buffer;
-                SizeOfAllUnicodeStrings += ParamStringA.MaximumLength;
-            }
-        }
-        else {
-            // it's not a unicode string
-            ParameterList[nParam] = HardErrorMessage->Parameters[nParam];
-        }
-    }
-
-    NtClose(hProcess);
-
-    // get text string of the error code
-    Status = RtlFindMessage(
-        (PVOID)GetModuleHandle(TEXT("ntdll")),
-        (ULONG_PTR)RT_MESSAGETABLE,
-        LANG_NEUTRAL,
-        HardErrorMessage->Status,
-        &MessageResource );
-    if( !NT_SUCCESS(Status) ) {
-        // WE HAVE TO DISPLAY HERE: "Unknown hard error"
-        if( ClientFileNameU.Buffer ) {
-            szxCaptionText = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ClientFileNameU.MaximumLength+64);
-            wsprintfW(szxCaptionText, L"%s - %hs", ClientFileNameU.Buffer, "Application Error");
-        } else {
-            szxCaptionText = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 64);
-            wsprintfW(szxCaptionText, L"System - Application Error");
-        }
-        MessageBody = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 38);
-        wsprintfA(MessageBody, "Unknown hard error");
-    }
-    else {
-        LPSTR NtStatusString;
-        UNICODE_STRING MessageU;
-        ANSI_STRING MessageA;
-        USHORT CaptionSize = 0;
-
-        if( !MessageResource->Flags ) {
-            /* we've got an ansi string */
-            DPRINT("MessageResource->Text=%s\n", (PSTR)MessageResource->Text);
-            RtlInitAnsiString(&MessageA, MessageResource->Text);
-        }
-        else {
-            /* we've got a unicode string */
-            DPRINT("MessageResource->Text=%S\n", (PWSTR)MessageResource->Text);
-            RtlInitUnicodeString(&MessageU, (PWSTR)MessageResource->Text);
-            RtlUnicodeStringToAnsiString(&MessageA, &MessageU, TRUE);
-        }
-
-        // check whether a caption exists
-        if( *MessageA.Buffer == '{' ) {
-            // get size of the caption
-            for( CaptionSize = 0; (CaptionSize < MessageA.Length) && ('}' != MessageA.Buffer[CaptionSize]); CaptionSize++);
-
-            CaptionText = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CaptionSize);
-            RtlCopyMemory(CaptionText, MessageA.Buffer+1, CaptionSize-1);
-            CaptionSize += 2; // "}\r\n" - 3
-
-            szxCaptionText = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(wchar_t)*CaptionSize+ClientFileNameU.MaximumLength+128);
-            if( ClientFileNameU.Buffer ) {
-                wsprintfW(szxCaptionText, L"%s - %hs", ClientFileNameU.Buffer, CaptionText);
-            } else {
-                wsprintfW(szxCaptionText, L"System - %hs", CaptionText);
-            }
-            RtlFreeHeap (RtlGetProcessHeap(), 0, CaptionText);
-        }
-        else {
-            if( ClientFileNameU.Buffer ) {
-                szxCaptionText = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ClientFileNameU.MaximumLength);
-                wsprintfW(szxCaptionText, L"%s", ClientFileNameU.Buffer);
-            } else {
-                szxCaptionText = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 14); // 14 - "System\0\0"
-                wsprintfW(szxCaptionText, L"System");
-            }
-        }
-        DPRINT("ParameterList[0]=0x%lx\n", ParameterList[0]);
-        if( STATUS_UNHANDLED_EXCEPTION == HardErrorMessage->Status )
-        {
-            PRTL_MESSAGE_RESOURCE_ENTRY MsgResException;
-            MessageBody = NULL;
-            Status = RtlFindMessage(
-                (PVOID)GetModuleHandle(TEXT("ntdll")),
-                (ULONG_PTR)RT_MESSAGETABLE,
-                LANG_NEUTRAL,
-                ParameterList[0],
-                &MsgResException);
-
-            if( NT_SUCCESS(Status) )
-            {
-                UNICODE_STRING ExcMessageU;
-                ANSI_STRING ExcMessageA;
-                if( !MsgResException->Flags ) {
-                    /* we've got an ansi string */
-                    DPRINT("MsgResException->Text=%s\n", (PSTR)MsgResException->Text);
-                    RtlInitAnsiString(&ExcMessageA, MsgResException->Text);
-                }
-                else {
-                    /* we've got a unicode string */
-                    DPRINT("MsgResException->Text=%S\n", (PWSTR)MsgResException->Text);
-                    RtlInitUnicodeString(&ExcMessageU, (PWSTR)MsgResException->Text);
-                    RtlUnicodeStringToAnsiString(&ExcMessageA, &ExcMessageU, TRUE);
-                }
-
-                MessageBody = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, MsgResException->Length+SizeOfAllUnicodeStrings+1024); // 1024 is a magic number I think it should be enough
-                if( STATUS_ACCESS_VIOLATION == ParameterList[0] ) {
-                    LPSTR pOperationType;
-                    if( ParameterList[2] ) pOperationType = "written";
-                    else pOperationType = "read";
-                    wsprintfA(MessageBody, ExcMessageA.Buffer, ParameterList[1], ParameterList[3], pOperationType);
-                }
-                else if( STATUS_IN_PAGE_ERROR == ParameterList[0] ) {
-                    wsprintfA(MessageBody, ExcMessageA.Buffer, ParameterList[1], ParameterList[3], ParameterList[2]);
-                }
-            }
-            if( !MessageBody ) {
-                NtStatusString = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, MessageResource->Length-CaptionSize);
-                RtlCopyMemory(NtStatusString, MessageA.Buffer+CaptionSize, (MessageResource->Length-CaptionSize)-1);
-
-                MessageBody = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, MessageResource->Length+SizeOfAllUnicodeStrings+1024); // 1024 is a magic number I think it should be enough
-
-                wsprintfA(MessageBody, NtStatusString, 
-                    L"Unknown software exception",
-                    ParameterList[0],
-                    ParameterList[1]);
-
-                RtlFreeHeap (RtlGetProcessHeap(), 0, NtStatusString);
-            }
-        }
-        else
-        {
-            NtStatusString = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, MessageResource->Length-CaptionSize);
-            RtlCopyMemory(NtStatusString, MessageA.Buffer+CaptionSize, (MessageResource->Length-CaptionSize)-1);
-
-            MessageBody = (LPSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, MessageResource->Length+SizeOfAllUnicodeStrings+1024); // 1024 is a magic number I think it should be enough
-
-            wsprintfA(MessageBody, NtStatusString, 
-                ParameterList[0],
-                ParameterList[1],
-                ParameterList[2],
-                ParameterList[3]);
-
-            RtlFreeHeap (RtlGetProcessHeap(), 0, NtStatusString);
-        }
-        if( MessageResource->Flags ) {
-            /* we've got a unicode string */
-            RtlFreeAnsiString(&MessageA);
-        }
-    }
-    if( ClientFileNameU.Buffer ) {
-        RtlFreeHeap (RtlGetProcessHeap(), 0, ClientFileNameU.Buffer);
-    }
-
-    szxMessageBody = (LPWSTR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(wchar_t)*(strlen(MessageBody)+1));
-    wsprintfW(szxMessageBody, L"%hs", MessageBody);
-    RtlFreeHeap (RtlGetProcessHeap(), 0, MessageBody);
-
-    switch ( HardErrorMessage->ValidResponseOptions )
-    {
-    case OptionAbortRetryIgnore:
-        responce = MB_ABORTRETRYIGNORE;
-        break;
-
-    case OptionOk:
-        responce = MB_OK;
-        break;
-
-    case OptionOkCancel:
-        responce = MB_OKCANCEL;
-        break;
-
-    case OptionRetryCancel:
-        responce = MB_RETRYCANCEL;
-        break;
-
-    case OptionYesNo:
-        responce = MB_YESNO;
-        break;
-
-    case OptionYesNoCancel:
-        responce = MB_YESNOCANCEL;
-        break;
-
-    case OptionShutdownSystem:
-        // XZ??
-        break;
-
-    default:
-        DPRINT1("Wrong option: ValidResponseOptions = %d\n", HardErrorMessage->ValidResponseOptions);
-        ASSERT(FALSE);
-        break;
-    }
-
-    // FIXME: We should not use MessageBox !!!!
-    DPRINT1("%S\n", szxMessageBody);
-    MessageBoxResponse = MessageBoxW(0, szxMessageBody, szxCaptionText, responce|MB_ICONERROR|MB_SYSTEMMODAL|MB_SETFOREGROUND);
-
-    RtlFreeHeap (RtlGetProcessHeap(), 0, szxMessageBody);
-    RtlFreeHeap (RtlGetProcessHeap(), 0, szxCaptionText);
-
-    switch( MessageBoxResponse )
-    {
-    case IDOK:
-        HardErrorMessage->Response = ResponseOk;
-        break;
-
-    case IDCANCEL:
-        HardErrorMessage->Response = ResponseCancel;
-        break;
-
-    case IDYES:
-        HardErrorMessage->Response = ResponseYes;
-        break;
-
-    case IDNO:
-        HardErrorMessage->Response = ResponseNo;
-        break;
-
-    case IDABORT:
-        HardErrorMessage->Response = ResponseAbort;
-        break;
-
-    case IDIGNORE:
-        HardErrorMessage->Response = ResponseIgnore;
-        break;
-
-    case IDRETRY:
-        HardErrorMessage->Response = ResponseRetry;
-        break;
-
-    case 10://IDTRYAGAIN:
-        HardErrorMessage->Response = ResponseTryAgain;
-        break;
-
-    case 11://IDCONTINUE:
-        HardErrorMessage->Response = ResponseContinue;
-        break;
-
-    default:
-        ASSERT(FALSE);
-        break;
-    }
-
-    return TRUE;
-}
-
-
 BOOL WINAPI
 Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
                        PCSRSS_OBJECT_DEFINITION *ObjectDefinitions,
diff --git a/subsystems/win32/csrss/win32csr/harderror.c b/subsystems/win32/csrss/win32csr/harderror.c
new file mode 100644 (file)
index 0000000..a1b5a5d
--- /dev/null
@@ -0,0 +1,552 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS system libraries
+ * FILE:            subsys/csrss/win32csr/dllmain.c
+ * PURPOSE:         Initialization
+ * PROGRAMMERS:     Dmitry Philippov (shedon@mail.ru)
+ *                  Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#define NDEBUG
+#include "w32csr.h"
+#include <debug.h>
+#include <strsafe.h>
+
+#define IDTRYAGAIN 10
+#define IDCONTINUE 11
+
+/* FUNCTIONS *****************************************************************/
+
+static
+NTSTATUS
+CsrpGetClientFileName(
+    OUT PUNICODE_STRING ClientFileNameU,
+    HANDLE hProcess)
+{
+    PLIST_ENTRY ModuleListHead;
+    PLIST_ENTRY Entry;
+    PLDR_DATA_TABLE_ENTRY Module;
+    PPEB_LDR_DATA Ldr;
+    PROCESS_BASIC_INFORMATION ClientBasicInfo;
+    LDR_DATA_TABLE_ENTRY ModuleData;
+    PVOID ClientDllBase;
+    NTSTATUS Status;
+    PPEB Peb;
+
+    /* Initialize string */
+    ClientFileNameU->MaximumLength = 0;
+    ClientFileNameU->Length = 0;
+    ClientFileNameU->Buffer = NULL;
+
+    /* Query process information */
+    Status = NtQueryInformationProcess(hProcess,
+                                       ProcessBasicInformation,
+                                       &ClientBasicInfo,
+                                       sizeof(ClientBasicInfo),
+                                       NULL);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    Peb = ClientBasicInfo.PebBaseAddress;
+    if (!Peb) return STATUS_UNSUCCESSFUL;
+
+    Status = NtReadVirtualMemory(hProcess, &Peb->Ldr, &Ldr, sizeof(Ldr), NULL);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    ModuleListHead = &Ldr->InLoadOrderModuleList;
+    Status = NtReadVirtualMemory(hProcess,
+                                 &ModuleListHead->Flink,
+                                 &Entry,
+                                 sizeof(Entry),
+                                 NULL);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    if (Entry == ModuleListHead) return STATUS_UNSUCCESSFUL;
+
+    Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
+
+    Status = NtReadVirtualMemory(hProcess,
+                                 Module,
+                                 &ModuleData,
+                                 sizeof(ModuleData),
+                                 NULL);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    Status = NtReadVirtualMemory(hProcess,
+                                 &Peb->ImageBaseAddress,
+                                 &ClientDllBase,
+                                 sizeof(ClientDllBase),
+                                 NULL);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    if (ClientDllBase != ModuleData.DllBase) return STATUS_UNSUCCESSFUL;
+
+    ClientFileNameU->MaximumLength = ModuleData.BaseDllName.MaximumLength;
+    ClientFileNameU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                              HEAP_ZERO_MEMORY,
+                                              ClientFileNameU->MaximumLength);
+
+    Status = NtReadVirtualMemory(hProcess,
+                                 ModuleData.BaseDllName.Buffer,
+                                 ClientFileNameU->Buffer,
+                                 ClientFileNameU->MaximumLength,
+                                 NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        RtlFreeHeap(RtlGetProcessHeap(), 0, ClientFileNameU->Buffer);
+        ClientFileNameU->Buffer = NULL;
+        ClientFileNameU->MaximumLength = 0;
+        return Status;
+    }
+
+    ClientFileNameU->Length = wcslen(ClientFileNameU->Buffer)*sizeof(wchar_t);
+    DPRINT("ClientFileNameU=\'%wZ\'\n", &ClientFileNameU);
+
+    return STATUS_SUCCESS;
+}
+
+
+static
+NTSTATUS
+CsrpCaptureStringParameters(
+    OUT PULONG_PTR Parameters,
+    OUT PULONG SizeOfAllUnicodeStrings,
+    IN PHARDERROR_MSG HardErrorMessage,
+    HANDLE hProcess)
+{
+    ULONG nParam, UnicodeStringParameterMask, Size = 0;
+    NTSTATUS Status;
+    UNICODE_STRING TempStringU;
+    PWSTR ParamString;
+
+    UnicodeStringParameterMask = HardErrorMessage->UnicodeStringParameterMask;
+
+    /* Read all strings from client space */
+    for (nParam = 0; 
+         nParam < HardErrorMessage->NumberOfParameters; 
+         nParam++, UnicodeStringParameterMask >>= 1)
+    {
+        Parameters[nParam] = 0;
+
+        /* Check if the current parameter is a unicode string */
+        if (UnicodeStringParameterMask & 0x01)
+        {
+            /* Read the UNICODE_STRING from the process memory */
+            Status = NtReadVirtualMemory(hProcess,
+                                         (PVOID)HardErrorMessage->Parameters[nParam],
+                                         &TempStringU,
+                                         sizeof(TempStringU),
+                                         NULL);
+
+            if (!NT_SUCCESS(Status)) return Status;
+
+            /* Allocate a buffer for the string */
+            ParamString = RtlAllocateHeap(RtlGetProcessHeap(),
+                                          HEAP_ZERO_MEMORY,
+                                          TempStringU.Length + sizeof(WCHAR));
+
+            if (!ParamString)
+            {
+                DPRINT1("Cannot allocate memory %d\n", TempStringU.Length);
+                return STATUS_NO_MEMORY;
+            }
+
+            /* Read the string buffer from the process memory */
+            Status = NtReadVirtualMemory(hProcess,
+                                         TempStringU.Buffer,
+                                         ParamString,
+                                         TempStringU.Length,
+                                         NULL);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("NtReadVirtualMemory failed with code: %lx\n", Status);
+                RtlFreeHeap(RtlGetProcessHeap(), 0, ParamString);
+                return Status;
+            }
+
+            /* Zero terminate the string */
+            ParamString[TempStringU.Length / sizeof(WCHAR)] = 0;
+            DPRINT("ParamString=\'%S\'\n", ParamString);
+
+            Parameters[nParam] = (ULONG_PTR)ParamString;
+            Size += TempStringU.Length;
+        }
+        else
+        {
+            /* It's not a unicode string */
+            Parameters[nParam] = HardErrorMessage->Parameters[nParam];
+        }
+    }
+
+    *SizeOfAllUnicodeStrings = Size;
+    return STATUS_SUCCESS;
+}
+
+static
+VOID
+CsrpFreeStringParameters(
+    IN OUT PULONG_PTR Parameters,
+    IN PHARDERROR_MSG HardErrorMessage)
+{
+    ULONG nParam, UnicodeStringParameterMask;
+
+    UnicodeStringParameterMask = HardErrorMessage->UnicodeStringParameterMask;
+
+    /* Loop all parameters */
+    for (nParam = 0; 
+         nParam < HardErrorMessage->NumberOfParameters; 
+         nParam++, UnicodeStringParameterMask >>= 1)
+    {
+        /* Check if the current parameter is a string */
+        if (UnicodeStringParameterMask & 0x01)
+        {
+            /* Free the string buffer */
+            RtlFreeHeap(RtlGetProcessHeap(), 0, (PVOID)Parameters[nParam]);
+        }
+    }
+}
+
+
+static
+NTSTATUS
+CsrpFormatMessages(
+    OUT PUNICODE_STRING TextStringU,
+    OUT PUNICODE_STRING CaptionStringU,
+    IN  PULONG_PTR Parameters,
+    IN  ULONG SizeOfStrings,
+    IN  PHARDERROR_MSG Message,
+    IN  HANDLE hProcess)
+{
+    NTSTATUS Status;
+    UNICODE_STRING FileNameU, TempStringU, FormatU;
+    ANSI_STRING FormatA;
+    PRTL_MESSAGE_RESOURCE_ENTRY MessageResource;
+    PWSTR FormatString;
+    ULONG Size;
+
+    /* Get the file name of the client process */
+    CsrpGetClientFileName(&FileNameU, hProcess);
+
+    /* Check if we have a file name */
+    if (!FileNameU.Buffer)
+    {
+        /* No, use system */
+        RtlInitUnicodeString(&FileNameU, L"System");
+    }
+
+    /* Get text string of the error code */
+    Status = RtlFindMessage(GetModuleHandleW(L"ntdll"),
+                            (ULONG_PTR)RT_MESSAGETABLE,
+                            LANG_NEUTRAL,
+                            Message->Status,
+                            &MessageResource);
+
+    if (NT_SUCCESS(Status))
+    {
+        if (MessageResource->Flags)
+        {
+            RtlInitUnicodeString(&FormatU, (PWSTR)MessageResource->Text);
+            FormatA.Buffer = NULL;
+        }
+        else
+        {
+            RtlInitAnsiString(&FormatA, MessageResource->Text);
+            RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE);
+        }
+    }
+    else
+    {
+        /* Fall back to hardcoded value */
+        RtlInitUnicodeString(&FormatU, L"Unknown Hard Error");
+        FormatA.Buffer = NULL;
+    }
+
+    FormatString = FormatU.Buffer;
+
+    /* Check whether a caption exists */
+    if (FormatString[0] == L'{')
+    {
+        /* Set caption start */
+        TempStringU.Buffer = ++FormatString;
+
+        /* Get size of the caption */
+        for (Size = 0; *FormatString != 0 && *FormatString != L'}'; Size++)
+            FormatString++;
+
+        /* Skip '}', '\r', '\n' */
+        FormatString += 3;
+
+        TempStringU.Length = Size * sizeof(WCHAR);
+        TempStringU.MaximumLength = TempStringU.Length;
+    }
+    else
+    {
+        /* FIXME: Set string based on severity */
+        RtlInitUnicodeString(&TempStringU, L"Application Error");
+    }
+
+    /* Calculate buffer length for the caption */
+    CaptionStringU->MaximumLength = FileNameU.Length + TempStringU.Length +
+                                    4 * sizeof(WCHAR);
+
+    /* Allocate a buffer for the caption */
+    CaptionStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                             HEAP_ZERO_MEMORY,
+                                             CaptionStringU->MaximumLength);
+
+    /* Append the file name, seperator and the caption text */
+    CaptionStringU->Length = 0;
+    RtlAppendUnicodeStringToString(CaptionStringU, &FileNameU);
+    RtlAppendUnicodeToString(CaptionStringU, L" - ");
+    RtlAppendUnicodeStringToString(CaptionStringU, &TempStringU);
+
+    /* Zero terminate the buffer */
+    CaptionStringU->Buffer[CaptionStringU->Length] = 0;
+
+    /* Free the file name buffer */
+    RtlFreeUnicodeString(&FileNameU);
+
+    /* Check if this is an exception message */
+    if (Message->Status == STATUS_UNHANDLED_EXCEPTION)
+    {
+        /* Handle special cases */
+        if (Parameters[0] == STATUS_ACCESS_VIOLATION)
+        {
+            Parameters[0] = Parameters[1];
+            Parameters[1] = Parameters[3];
+            if (Parameters[2]) Parameters[2] = (ULONG_PTR)L"written";
+            else Parameters[2] = (ULONG_PTR)L"read";
+            MessageResource = NULL;
+        }
+        else if (Parameters[0] == STATUS_IN_PAGE_ERROR)
+        {
+            Parameters[0] = Parameters[1];
+            Parameters[1] = Parameters[3];
+            MessageResource = NULL;
+        }
+        else
+        {
+            /* Fall back to hardcoded value */
+            Parameters[2] = Parameters[1];
+            Parameters[1] = Parameters[0];
+            Parameters[0] = (ULONG_PTR)L"unknown software exception";
+        }
+
+        if (!MessageResource)
+        {
+            /* Get text string of the exception code */
+            Status = RtlFindMessage(GetModuleHandleW(L"ntdll"),
+                                    (ULONG_PTR)RT_MESSAGETABLE,
+                                    LANG_NEUTRAL,
+                                    Parameters[0],
+                                    &MessageResource);
+
+            if (NT_SUCCESS(Status))
+            {
+                if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU);
+
+                if (MessageResource->Flags)
+                {
+                    RtlInitUnicodeString(&FormatU, (PWSTR)MessageResource->Text);
+                    FormatA.Buffer = NULL;
+                }
+                else
+                {
+                    RtlInitAnsiString(&FormatA, MessageResource->Text);
+                    RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE);
+                }
+            }
+            else
+            {
+                /* Fall back to hardcoded value */
+                Parameters[2] = Parameters[1];
+                Parameters[1] = Parameters[0];
+                Parameters[0] = (ULONG_PTR)L"unknown software exception";
+            }
+        }
+    }
+
+    /* Calculate length of text buffer */
+    TextStringU->MaximumLength = wcslen(FormatString) * sizeof(WCHAR) +
+                                     SizeOfStrings + 42 * sizeof(WCHAR);
+    
+    /* Allocate a buffer for the text */
+    TextStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                          HEAP_ZERO_MEMORY,
+                                          TextStringU->MaximumLength);
+
+    /* Wrap in SEH to protect from invalid string parameters */
+    _SEH2_TRY
+    {
+        /* Print the string into the buffer */
+        StringCbPrintfW(TextStringU->Buffer,
+                        TextStringU->MaximumLength,
+                        FormatString,
+                        Parameters[0],
+                        Parameters[1],
+                        Parameters[2],
+                        Parameters[3],
+                        Parameters[4]);
+        Status = STATUS_SUCCESS;
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Set error and free buffers */
+        Status = _SEH2_GetExceptionCode();
+        RtlFreeHeap(RtlGetProcessHeap(), 0, TextStringU->Buffer);
+        RtlFreeHeap(RtlGetProcessHeap(), 0, CaptionStringU->Buffer);
+    }
+    _SEH2_END
+
+    if (NT_SUCCESS(Status))
+    {
+        TextStringU->Length = wcslen(TextStringU->Buffer) * sizeof(WCHAR);
+    }
+
+    if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU);
+
+    return Status;
+}
+
+static
+ULONG
+CsrpMessageBox(
+    PWSTR Text,
+    PWSTR Caption,
+    ULONG ValidResponseOptions,
+    ULONG Severity)
+{
+    ULONG Type, MessageBoxResponse;
+
+    /* Set the message box type */
+    switch (ValidResponseOptions)
+    {
+        case OptionAbortRetryIgnore:
+            Type = MB_ABORTRETRYIGNORE;
+            break;
+        case OptionOk:
+            Type = MB_OK;
+            break;
+        case OptionOkCancel:
+            Type = MB_OKCANCEL;
+            break;
+        case OptionRetryCancel:
+            Type = MB_RETRYCANCEL;
+            break;
+        case OptionYesNo:
+            Type = MB_YESNO;
+            break;
+        case OptionYesNoCancel:
+            Type = MB_YESNOCANCEL;
+            break;
+        case OptionShutdownSystem:
+            Type = MB_RETRYCANCEL; // FIXME???
+            break;
+        /* Anything else is invalid */
+        default:
+            return ResponseNotHandled;
+    }
+
+    /* Set severity */
+    if (Severity == STATUS_SEVERITY_INFORMATIONAL) Type |= MB_ICONINFORMATION;
+    else if (Severity == STATUS_SEVERITY_WARNING) Type |= MB_ICONWARNING;
+    else if (Severity == STATUS_SEVERITY_ERROR) Type |= MB_ICONERROR;
+
+    Type |= MB_SYSTEMMODAL | MB_SETFOREGROUND;
+
+    DPRINT("Text = '%S', Caption = '%S', Severity = %d, Type = 0x%lx\n", 
+           Text, Caption, Severity, Type);
+
+    /* Display a message box */
+    MessageBoxResponse = MessageBoxW(0, Text, Caption, Type);
+
+    /* Return response value */
+    switch (MessageBoxResponse)
+    {
+        case IDOK:       return ResponseOk;
+        case IDCANCEL:   return ResponseCancel;
+        case IDYES:      return ResponseYes;
+        case IDNO:       return ResponseNo;
+        case IDABORT:    return ResponseAbort;
+        case IDIGNORE:   return ResponseIgnore;
+        case IDRETRY:    return ResponseRetry;
+        case IDTRYAGAIN: return ResponseTryAgain;
+        case IDCONTINUE: return ResponseContinue;
+    }
+
+    return ResponseNotHandled;
+}
+
+BOOL
+WINAPI
+Win32CsrHardError(
+    IN PCSRSS_PROCESS_DATA ProcessData,
+    IN PHARDERROR_MSG Message)
+{
+    ULONG_PTR Parameters[MAXIMUM_HARDERROR_PARAMETERS];
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING TextU, CaptionU;
+    NTSTATUS Status;
+    HANDLE hProcess;
+    ULONG Size;
+
+    /* Default to not handled */
+    Message->Response = ResponseNotHandled;
+
+    /* Make sure we don't have too many parameters */
+    if (Message->NumberOfParameters > MAXIMUM_HARDERROR_PARAMETERS)
+        Message->NumberOfParameters = MAXIMUM_HARDERROR_PARAMETERS;
+
+    /* Initialize object attributes */
+    InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
+
+    /* Open client process */
+    Status = NtOpenProcess(&hProcess,
+                           PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
+                           &ObjectAttributes,
+                           &Message->h.ClientId);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("NtOpenProcess failed with code: %lx\n", Status);
+        return FALSE;
+    }
+
+    /* Capture all string parameters from the process memory */
+    Status = CsrpCaptureStringParameters(Parameters, &Size, Message, hProcess);
+    if (!NT_SUCCESS(Status))
+    {
+        NtClose(hProcess);
+        return FALSE;
+    }
+
+    /* Format the caption and message box text */
+    Status = CsrpFormatMessages(&TextU,
+                                &CaptionU,
+                                Parameters,
+                                Size,
+                                Message,
+                                hProcess);
+
+    /* Cleanup */
+    CsrpFreeStringParameters(Parameters, Message);
+    NtClose(hProcess);
+
+    if (!NT_SUCCESS(Status))
+    {
+       return FALSE;
+    }
+
+    /* Display the message box */
+    Message->Response = CsrpMessageBox(TextU.Buffer,
+                                       CaptionU.Buffer,
+                                       Message->ValidResponseOptions,
+                                       (ULONG)Message->Status >> 30);
+
+    RtlFreeUnicodeString(&TextU);
+    RtlFreeUnicodeString(&CaptionU);
+
+    return TRUE;
+}
+
index f6f0f4e..5ecc378 100644 (file)
 
 /* shared header with console.dll */
 #include "console.h"
+
+BOOL
+WINAPI
+Win32CsrHardError(
+    IN PCSRSS_PROCESS_DATA ProcessData,
+    IN PHARDERROR_MSG Message);
+
 /* EOF */
index 7a14f63..eec81fc 100644 (file)
@@ -14,6 +14,7 @@
        <library>advapi32</library>
        <library>win32ksys</library>
        <library>psapi</library>
+       <library>pseh</library>
        <pch>w32csr.h</pch>
        <file>alias.c</file>
        <file>conio.c</file>
@@ -21,6 +22,7 @@
        <file>dllmain.c</file>
        <file>exitros.c</file>
        <file>guiconsole.c</file>
+       <file>harderror.c</file>
        <file>tuiconsole.c</file>
        <file>appswitch.c</file>
        <file>win32csr.rc</file>
index c0e8bbf..30591d3 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index cbc0129..de56971 100644 (file)
@@ -8,7 +8,7 @@
  *                  Gregor Anich
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 35ee870..ebea73d 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMMERS:     Jason Filby
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 2106d9b..3810024 100644 (file)
@@ -8,7 +8,7 @@
  *                  Gregor Anich
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 79a71c9..ca09cee 100644 (file)
@@ -7,7 +7,7 @@
  *                  Magnus Olsen
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index edf3f63..6c4704b 100644 (file)
@@ -8,7 +8,7 @@
  *                  Gregor Anich
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index da86647..859e950 100644 (file)
@@ -7,7 +7,7 @@
  *                  Magnus Olsen
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 4ae4f8b..1626b8e 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index cfbdb0a..95b09cb 100644 (file)
@@ -8,7 +8,7 @@
  *                  Gregor Anich
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 21bd2c3..c31c262 100644 (file)
@@ -6,7 +6,7 @@
 * PROGRAMMER:        Gregor Schneider, <grschneider AT gmail DOT com>
 */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 579014a..b6d479d 100644 (file)
@@ -8,7 +8,7 @@
  *                  Gregor Schneider
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 30ba88f..34b2930 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:        Jason Filby
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 3c65aaa..afac0e8 100644 (file)
@@ -9,7 +9,7 @@
  *        2/10/1999: Created
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index d9bfe0e..0235d0f 100644 (file)
@@ -27,7 +27,7 @@
  *                 21/8/1999: Created
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 1cabfb9..73a477d 100644 (file)
@@ -26,7 +26,7 @@
  *        8/18/1999: Created
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 91b3982..9e2e722 100644 (file)
@@ -27,7 +27,7 @@
  *                 11/7/1999: Created
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 301497a..0e51ea0 100644 (file)
@@ -7,7 +7,7 @@
  *                    Timo Kreuzer
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 900812e..cb6ff38 100644 (file)
@@ -8,7 +8,7 @@
 
 /** Includes ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 1337e29..3c3d1d7 100644 (file)
@@ -7,7 +7,7 @@
  *                    Timo Kreuzer
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index e978786..d38c32a 100644 (file)
@@ -8,7 +8,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 #define NDEBUG
 #include <debug.h>
 
index bb65ef6..af544c9 100644 (file)
@@ -18,7 +18,7 @@
  */
 /* $Id$ */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index aed25f0..5628610 100644 (file)
@@ -29,7 +29,7 @@
 /* TODO: Check how the WNDOBJ implementation should behave with a driver on windows.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index d81b382..d78da06 100644 (file)
@@ -1,4 +1,4 @@
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index ebee480..2ca5fe9 100644 (file)
@@ -28,7 +28,7 @@
 
 /* INCLUDES *****************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 7559b17..c3ef653 100644 (file)
@@ -27,7 +27,7 @@
  *                 3/7/1999: Created
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 049c0a9..a67b47a 100644 (file)
@@ -19,7 +19,7 @@
  * $Id$
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 39de582..7e445d7 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 3beb023..a49e4fe 100644 (file)
@@ -27,7 +27,7 @@
  *                 3/7/1999: Created
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index d96e8dd..f5f6b2f 100644 (file)
@@ -9,7 +9,7 @@
  */
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 81d1e67..29cd723 100644 (file)
@@ -27,7 +27,7 @@
  *                 3/7/1999: Created
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index e69ff02..381abc4 100644 (file)
@@ -25,7 +25,7 @@
  * PROGRAMER:         Ge van Geldorp
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 5ef403d..d09d4c9 100644 (file)
@@ -1,4 +1,4 @@
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index df6a1da..0b9354b 100644 (file)
@@ -18,7 +18,7 @@
  */
 /* $Id$ */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index ee5711c..932d93d 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:        Jason Filby
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 6ab902a..14cbc5b 100644 (file)
@@ -1,5 +1,5 @@
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 5a85d1a..c081ed5 100644 (file)
@@ -12,7 +12,7 @@
  *   refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 4ef5954..bca2244 100644 (file)
@@ -27,7 +27,7 @@
  *        4/6/2004: Created
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index fcdd0b8..27d0684 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:        Timo Kreuzer (timo.kreuzer@reactos.org)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #include <intrin.h>
 
index c241b9e..83f3a35 100644 (file)
@@ -18,4 +18,6 @@ IntGdiModifyWorldTransform(PDC pDc,
                            DWORD Mode);
 
 VOID FASTCALL IntMirrorWindowOrg(PDC);
-void FASTCALL IntFixIsotropicMapping(PDC dc);
+void FASTCALL IntFixIsotropicMapping(PDC);
+LONG FASTCALL IntCalcFillOrigin(PDC);
+PPOINTL FASTCALL IntptlBrushOrigin(PDC pdc,LONG,LONG);
\ No newline at end of file
index b616bdc..48b0e92 100644 (file)
@@ -177,6 +177,8 @@ HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC);
 BOOL FASTCALL IntGdiCleanDC(HDC hDC);
 VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS);
 INT FASTCALL IntGdiGetDeviceCaps(PDC,INT);
+BOOL FASTCALL MakeInfoDC(PDC,BOOL);
+BOOL FASTCALL IntSetDefaultRegion(PDC);
 
 extern PPDEVOBJ pPrimarySurface;
 
@@ -228,6 +230,5 @@ DC_vSelectPalette(PDC pdc, PPALETTE ppal)
     pdc->dclevel.ppal = ppal;
 }
 
-BOOL FASTCALL
-IntPrepareDriverIfNeeded(VOID);
+BOOL FASTCALL IntPrepareDriverIfNeeded(VOID);
 extern PDEVOBJ PrimarySurface;
index 50ed2e6..6b9a7fd 100644 (file)
@@ -131,3 +131,6 @@ GDIOBJ_IncrementShareCount(POBJ Object)
 #endif
 
 INT FASTCALL GreGetObjectOwner(HGDIOBJ, GDIOBJTYPE);
+
+#define GDIOBJ_GetKernelObj(Handle) \
+  ((PGDI_TABLE_ENTRY)&GdiHandleTable->Entries[GDI_HANDLE_GET_INDEX(Handle)])->KernelData
index 5752481..c751f3a 100644 (file)
@@ -248,6 +248,16 @@ VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers,
    (message) == WM_NCRBUTTON##code || \
    (message) == WM_NCXBUTTON##code )
 
+#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
+#define WM_NCMOUSELAST  (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
+
+#define IS_MOUSE_MESSAGE(message) \
+    ((message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST) || \
+            (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST))
+
+#define IS_KBD_MESSAGE(message) \
+    (message == WM_KEYDOWN || message == WM_KEYUP)
+
 HANDLE FASTCALL
 IntMsqSetWakeMask(DWORD WakeMask);
 
index 4124509..ca0c3fa 100644 (file)
@@ -88,8 +88,8 @@ typedef struct _PDEVOBJ
 //  PVOID                     TypeOneInfo;
     PVOID                     pvGammaRamp;    /* Gamma ramp pointer. */
 //  PVOID                     RemoteTypeOne;
-//  ULONG                     ulHorzRes;
-//  ULONG                     ulVertRes;
+    ULONG                     ulHorzRes;
+    ULONG                     ulVertRes;
 //  PFN_DrvSetPointerShape    pfnDrvSetPointerShape;
 //  PFN_DrvMovePointer        pfnDrvMovePointer;
     PFN_DrvMovePointer        pfnMovePointer;
@@ -107,7 +107,7 @@ typedef struct _PDEVOBJ
 //  HANDLE                    hSpooler;       /* Handle to spooler, if spooler dev driver. */
 //  PVOID                     pDesktopId;
     PGRAPHICS_DEVICE          pGraphicsDevice;
-//  POINTL                    ptlOrigion;
+    POINTL                    ptlOrigion;
     PVOID                     pdmwDev;        /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */
 //  DWORD                     Unknown3;
     FLONG                     DxDd_Flags;     /* DxDD active status flags. */
@@ -141,4 +141,6 @@ typedef struct _PDEVEDD
     EDD_DIRECTDRAW_GLOBAL EDDgpl;
 } PDEVEDD, *PPDEVEDD;
 
+PSIZEL FASTCALL PDEV_sizl(PPDEVOBJ, PSIZEL);
+
 extern ULONG gdwDirectDrawContext;
index 57a5ec2..3fe9054 100644 (file)
@@ -3,6 +3,8 @@
 #include "win32.h"
 #include "gdiobj.h"
 
+#define PDEV_SURFACE              0x80000000
+
 /* GDI surface object */
 typedef struct _SURFACE
 {
index 9803c8d..50a8756 100644 (file)
@@ -20,7 +20,7 @@
  *
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 8d106e7..040d3cc 100644 (file)
@@ -20,7 +20,7 @@
  *  Entry Point for win32k.sys
  */
 
-#include <w32k.h>
+#include <win32k.h>
 #include <include/napi.h>
 
 #define NDEBUG
index 5668ade..a40a5be 100644 (file)
@@ -1,4 +1,4 @@
-#include "w32k.h"
+#include "win32k.h"
 
 NTSTATUS _MmCopyFromCaller( PVOID Target, PVOID Source, UINT Bytes ) {
     NTSTATUS Status = STATUS_SUCCESS;
index e713f32..1219f94 100644 (file)
@@ -23,7 +23,7 @@
  *
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index c1c66ea..b7fcb2c 100644 (file)
@@ -27,7 +27,7 @@
  *       06-06-2001  CSH  Created
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 263ed12..1e2281a 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:        Timo Kreuzer (timo.kreuzer@reactos.org)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 6b4fc0c..11ffc1e 100644 (file)
@@ -19,7 +19,7 @@
    Boston, MA 02110-1301, USA.
 */
 
-#include <w32k.h>
+#include <win32k.h>
 
 /*
  * FIXME! Is there a better algorithm. like FT_MulDiv
index f03de06..fcaefab 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:        Timo Kreuzer (timo.kreuzer@reactos.org)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 7e1da4b..06f8d3e 100644 (file)
@@ -9,7 +9,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 /* FUNCTIONS *****************************************************************/
 VOID
index e8b1908..c371121 100644 (file)
@@ -17,7 +17,7 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 8371ff1..f30f08c 100644 (file)
@@ -13,7 +13,7 @@
  *   NtGdiDdUnlock and NtGdiDdUnlockD3D ultimately call the same function in dxg.sys 
  */
 
-#include <w32k.h>
+#include <win32k.h>
 #include <debug.h>
 
 
index 9cccbce..a1207ed 100644 (file)
@@ -8,7 +8,7 @@
  *       19/1-2006   Magnus Olsen
  */
 
-#include <w32k.h>
+#include <win32k.h>
 #include <debug.h>
 
 /************************************************************************/
index 3abbd18..19b6931 100644 (file)
@@ -8,7 +8,7 @@
  *       19/1-2006   Magnus Olsen
  */
 
-#include <w32k.h>
+#include <win32k.h>
 #include <debug.h>
 
 PGD_DXDDSTARTUPDXGRAPHICS gpfnStartupDxGraphics = NULL;
index 388be27..ae46f88 100644 (file)
@@ -8,7 +8,7 @@
  *       19/7-2006  Magnus Olsen
  */
 
-#include <w32k.h>
+#include <win32k.h>
 #include <debug.h>
 
 /************************************************************************/
index de5fe6a..a03be0f 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 
-#include <w32k.h>
+#include <win32k.h>
 #include <debug.h>
 
 /************************************************************************/
index 586c496..58413a5 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMMERS:      Magnus Olsen (magnus@greatlord.com)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 #include <debug.h>
 
 HSEMAPHORE  ghsemShareDevLock = NULL;
index 675b596..f55525a 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 
-#include <w32k.h>
+#include <win32k.h>
 #include <debug.h>
 
 /************************************************************************/
index 08c3f94..bc80584 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 
-#include <w32k.h>
+#include <win32k.h>
 #include <debug.h>
 
 /************************************************************************/
index 544eced..b59f1d1 100644 (file)
@@ -49,7 +49,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 9a8de74..eb4db06 100644 (file)
@@ -14,7 +14,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 866bac1..dc8496d 100644 (file)
@@ -9,7 +9,7 @@
  */
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index ee5e33b..c75dc05 100644 (file)
@@ -11,7 +11,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index f1755fe..b24b26f 100644 (file)
@@ -9,7 +9,7 @@
  */
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 55032c4..a44bbab 100644 (file)
@@ -7,7 +7,7 @@
  *                   Pablo Borobia <pborobia@gmail.com>
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index a1e425e..9487af5 100644 (file)
@@ -7,7 +7,7 @@
  * PROGRAMER:        Ge van Geldorp (ge@gse.nl)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 6c9532c..3fe0211 100644 (file)
@@ -36,7 +36,7 @@
  * CURICON_PROCESS structs starting at CurIcon->ProcessList.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 2a59f10..f5e2bd1 100644 (file)
@@ -7,7 +7,7 @@
  *
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 0f635d0..c5d76b2 100644 (file)
@@ -10,7 +10,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index c652e30..561171d 100644 (file)
@@ -9,7 +9,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 2dc8eae..d170983 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:         James Tabor (james.tabor@rectos.org)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 0f39b96..90702b4 100644 (file)
@@ -18,7 +18,7 @@
  *
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index f0ee364..e3766d8 100644 (file)
@@ -33,7 +33,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index bca944e..a71ea9b 100644 (file)
@@ -10,7 +10,7 @@
  *                   Copyright (C) 2002 Alexandre Julliard
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -1050,6 +1050,12 @@ NtUserCallNextHookEx(int Code,
 
     if (!HookObj) RETURN( 0);
 
+    /* Check that the first hook in the chain is not this hook */
+    NextObj = IntGetFirstHook(IntGetTable(HookObj), HookObj->HookId);
+
+    /* Its the same so it has already been called */
+    if (HookObj == NextObj) RETURN(0);
+
     UserReferenceObject(HookObj);
 
     Ansi = HookObj->Ansi;
index c2585f3..4ec1f1b 100644 (file)
@@ -40,7 +40,7 @@ windows/threads on destops not belonging to WinSta0 to set hotkeys (recieve noti
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index f0790e1..e86d14a 100644 (file)
@@ -10,7 +10,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 #include <ntddkbd.h>
 
 #define NDEBUG
@@ -204,6 +204,16 @@ MouseThreadMain(PVOID StartContext)
    NTSTATUS Status;
    MOUSE_ATTRIBUTES MouseAttr;
 
+   Status = Win32kInitWin32Thread(PsGetCurrentThread());
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT1("Win32K: Failed making keyboard thread a win32 thread.\n");
+      return; //(Status);
+   }
+
+   KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
+                       LOW_REALTIME_PRIORITY + 3);
+
    InitializeObjectAttributes(&MouseObjectAttributes,
                               &MouseDeviceName,
                               0,
@@ -713,6 +723,7 @@ KeyboardThreadMain(PVOID StartContext)
          for (;NumKeys;memcpy(&KeyInput, &NextKeyInput, sizeof(KeyInput)),
                NumKeys--)
          {
+            PKBL keyboardLayout = NULL;
             lParam = 0;
 
             IntKeyboardUpdateLeds(KeyboardDeviceHandle,
@@ -783,29 +794,30 @@ KeyboardThreadMain(PVOID StartContext)
             }
 
             /* Find the target thread whose locale is in effect */
-               FocusQueue = IntGetFocusMessageQueue();
-
-            /* This might cause us to lose hot keys, which are important
-             * (ctrl-alt-del secure attention sequence). Not sure if it
-             * can happen though.
-             */
-            if (!FocusQueue)
-               continue;
+            FocusQueue = IntGetFocusMessageQueue();
 
-            msg.lParam = lParam;
-            msg.hwnd = FocusQueue->FocusWindow;
+            if (FocusQueue)
+            {
+                msg.hwnd = FocusQueue->FocusWindow;
 
-            FocusThread = FocusQueue->Thread;
+                FocusThread = FocusQueue->Thread;
+                if (FocusThread && FocusThread->Tcb.Win32Thread)
+                {
+                    keyboardLayout = ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout;
+                }
+            }
+            if (!keyboardLayout)
+            {
+                keyboardLayout = W32kGetDefaultKeyLayout();
+            }
 
-            if (!(FocusThread && FocusThread->Tcb.Win32Thread &&
-                  ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout))
-               continue;
+            msg.lParam = lParam;
 
             /* This function uses lParam to fill wParam according to the
              * keyboard layout in use.
              */
             W32kKeyProcessMessage(&msg,
-                                  ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout->KBTables,
+                                  keyboardLayout->KBTables,
                                   KeyInput.Flags & KEY_E0 ? 0xE0 :
                                   (KeyInput.Flags & KEY_E1 ? 0xE1 : 0));
 
@@ -827,6 +839,11 @@ KeyboardThreadMain(PVOID StartContext)
                continue; /* Eat key up motion too */
             }
 
+            if (!FocusQueue)
+            {
+                /* There is no focused window to receive a keyboard message */
+                continue;
+            }
             /*
              * Post a keyboard message.
              */
@@ -1094,7 +1111,7 @@ IntMouseInput(MOUSEINPUT *mi)
    /*
     * Insert the messages into the system queue
     */
-   Msg.wParam = CurInfo->ButtonsDown;
+   Msg.wParam = 0;
    Msg.lParam = MAKELPARAM(MousePos.x, MousePos.y);
    Msg.pt = MousePos;
 
@@ -1117,6 +1134,7 @@ IntMouseInput(MOUSEINPUT *mi)
       gQueueKeyStateTable[VK_LBUTTON] |= 0xc0;
       Msg.message = SwapBtnMsg[0][SwapButtons];
       CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
+      Msg.wParam |= CurInfo->ButtonsDown;
       MsqInsertSystemMessage(&Msg);
    }
    else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
@@ -1124,6 +1142,7 @@ IntMouseInput(MOUSEINPUT *mi)
       gQueueKeyStateTable[VK_LBUTTON] &= ~0x80;
       Msg.message = SwapBtnMsg[1][SwapButtons];
       CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
+      Msg.wParam |= CurInfo->ButtonsDown;
       MsqInsertSystemMessage(&Msg);
    }
    if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
@@ -1131,6 +1150,7 @@ IntMouseInput(MOUSEINPUT *mi)
       gQueueKeyStateTable[VK_MBUTTON] |= 0xc0;
       Msg.message = WM_MBUTTONDOWN;
       CurInfo->ButtonsDown |= MK_MBUTTON;
+      Msg.wParam |= CurInfo->ButtonsDown;
       MsqInsertSystemMessage(&Msg);
    }
    else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
@@ -1138,6 +1158,7 @@ IntMouseInput(MOUSEINPUT *mi)
       gQueueKeyStateTable[VK_MBUTTON] &= ~0x80;
       Msg.message = WM_MBUTTONUP;
       CurInfo->ButtonsDown &= ~MK_MBUTTON;
+      Msg.wParam |= CurInfo->ButtonsDown;
       MsqInsertSystemMessage(&Msg);
    }
    if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
@@ -1145,6 +1166,7 @@ IntMouseInput(MOUSEINPUT *mi)
       gQueueKeyStateTable[VK_RBUTTON] |= 0xc0;
       Msg.message = SwapBtnMsg[0][!SwapButtons];
       CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
+      Msg.wParam |= CurInfo->ButtonsDown;
       MsqInsertSystemMessage(&Msg);
    }
    else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
@@ -1152,6 +1174,7 @@ IntMouseInput(MOUSEINPUT *mi)
       gQueueKeyStateTable[VK_RBUTTON] &= ~0x80;
       Msg.message = SwapBtnMsg[1][!SwapButtons];
       CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
+      Msg.wParam |= CurInfo->ButtonsDown;
       MsqInsertSystemMessage(&Msg);
    }
 
@@ -1168,15 +1191,15 @@ IntMouseInput(MOUSEINPUT *mi)
       if(mi->mouseData & XBUTTON1)
       {
          gQueueKeyStateTable[VK_XBUTTON1] |= 0xc0;
+         CurInfo->ButtonsDown |= MK_XBUTTON1;
          Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
-         CurInfo->ButtonsDown |= XBUTTON1;
          MsqInsertSystemMessage(&Msg);
       }
       if(mi->mouseData & XBUTTON2)
       {
          gQueueKeyStateTable[VK_XBUTTON2] |= 0xc0;
+         CurInfo->ButtonsDown |= MK_XBUTTON2;
          Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
-         CurInfo->ButtonsDown |= XBUTTON2;
          MsqInsertSystemMessage(&Msg);
       }
    }
@@ -1186,15 +1209,15 @@ IntMouseInput(MOUSEINPUT *mi)
       if(mi->mouseData & XBUTTON1)
       {
          gQueueKeyStateTable[VK_XBUTTON1] &= ~0x80;
+         CurInfo->ButtonsDown &= ~MK_XBUTTON1;
          Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
-         CurInfo->ButtonsDown &= ~XBUTTON1;
          MsqInsertSystemMessage(&Msg);
       }
       if(mi->mouseData & XBUTTON2)
       {
          gQueueKeyStateTable[VK_XBUTTON2] &= ~0x80;
+         CurInfo->ButtonsDown &= ~MK_XBUTTON2;
          Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
-         CurInfo->ButtonsDown &= ~XBUTTON2;
          MsqInsertSystemMessage(&Msg);
       }
    }
index ec07d34..8ee11dc 100644 (file)
@@ -12,7 +12,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 0c935a4..242147c 100644 (file)
@@ -28,7 +28,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -88,12 +88,12 @@ static VOID APIENTRY SetKeyState(DWORD key, DWORD vk, DWORD ext, BOOL down)
          gQueueKeyStateTable[vk] ^= KS_LOCK_BIT;
    }
 
-   if (ext && vk == VK_LSHIFT)
-      vk = VK_RSHIFT;
-   if (ext && vk == VK_LCONTROL)
-      vk = VK_RCONTROL;
-   if (ext && vk == VK_LMENU)
-      vk = VK_RMENU;
+   if (vk == VK_SHIFT)
+      vk = ext ? VK_RSHIFT : VK_LSHIFT;
+   if (vk == VK_CONTROL)
+      vk = ext ? VK_RCONTROL : VK_LCONTROL;
+   if (vk == VK_MENU)
+      vk = ext ? VK_RMENU : VK_LMENU;
 
    if (down)
       gQueueKeyStateTable[vk] |= KS_DOWN_BIT;
index 9bdbe02..3b1cd6a 100644 (file)
@@ -9,7 +9,7 @@
  */
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 1b244b0..3bd9201 100644 (file)
@@ -10,7 +10,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -645,6 +645,74 @@ co_IntTranslateMouseMessage(
    return FALSE;
 }
 
+BOOL ProcessMouseMessage(MSG* Msg, USHORT HitTest, UINT RemoveMsg)
+{
+    MOUSEHOOKSTRUCT MHook;
+    EVENTMSG Event;
+
+    Event.message = Msg->message;
+    Event.time    = Msg->time;
+    Event.hwnd    = Msg->hwnd;
+    Event.paramL  = Msg->pt.x;
+    Event.paramH  = Msg->pt.y;
+    co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
+
+
+    MHook.pt           = Msg->pt;
+    MHook.hwnd         = Msg->hwnd;
+    MHook.wHitTestCode = HitTest;
+    MHook.dwExtraInfo  = 0;
+    if (co_HOOK_CallHooks( WH_MOUSE,
+                           RemoveMsg ? HC_ACTION : HC_NOREMOVE,
+                           Msg->message,
+                           (LPARAM)&MHook ))
+    {
+        if (ISITHOOKED(WH_CBT))
+        {
+            MHook.pt           = Msg->pt;
+            MHook.hwnd         = Msg->hwnd;
+            MHook.wHitTestCode = HitTest;
+            MHook.dwExtraInfo  = 0;
+            co_HOOK_CallHooks( WH_CBT,
+                               HCBT_CLICKSKIPPED,
+                               Msg->message,
+                               (LPARAM)&MHook);
+        }
+        return FALSE;
+    }
+
+       return TRUE;
+}
+
+BOOL ProcessKeyboardMessage(MSG* Msg, UINT RemoveMsg)
+{
+   EVENTMSG Event;
+
+   Event.message = Msg->message;
+   Event.hwnd    = Msg->hwnd;
+   Event.time    = Msg->time;
+   Event.paramL  = (Msg->wParam & 0xFF) | (HIWORD(Msg->lParam) << 8);
+   Event.paramH  = Msg->lParam & 0x7FFF;
+   if (HIWORD(Msg->lParam) & 0x0100) Event.paramH |= 0x8000;
+   co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
+
+    if (co_HOOK_CallHooks( WH_KEYBOARD,
+                           RemoveMsg ? HC_ACTION : HC_NOREMOVE,
+                           LOWORD(Msg->wParam),
+                           Msg->lParam))
+    {
+        if (ISITHOOKED(WH_CBT))
+        {
+            /* skip this message */
+            co_HOOK_CallHooks( WH_CBT,
+                               HCBT_KEYSKIPPED,
+                               LOWORD(Msg->wParam),
+                               Msg->lParam );
+        }
+        return FALSE;
+    }
+       return TRUE;
+}
 /*
  * Internal version of PeekMessage() doing all the work
  */
@@ -662,7 +730,6 @@ co_IntPeekMessage( PUSER_MESSAGE Msg,
    BOOL Present, RemoveMessages;
    USER_REFERENCE_ENTRY Ref;
    USHORT HitTest;
-   MOUSEHOOKSTRUCT MHook;
 
    /* The queues and order in which they are checked are documented in the MSDN
       article on GetMessage() */
@@ -867,52 +934,20 @@ MessageFound:
       }
 
 MsgExit:
-      if ( ISITHOOKED(WH_MOUSE) &&
-           Msg->Msg.message >= WM_MOUSEFIRST &&
-           Msg->Msg.message <= WM_MOUSELAST )
-      {
-         MHook.pt           = Msg->Msg.pt;
-         MHook.hwnd         = Msg->Msg.hwnd;
-         MHook.wHitTestCode = HitTest;
-         MHook.dwExtraInfo  = 0;
-         if (co_HOOK_CallHooks( WH_MOUSE,
-                                RemoveMsg ? HC_ACTION : HC_NOREMOVE,
-                                Msg->Msg.message,
-                                (LPARAM)&MHook ))
-         {
-            if (ISITHOOKED(WH_CBT))
-            {
-                MHook.pt           = Msg->Msg.pt;
-                MHook.hwnd         = Msg->Msg.hwnd;
-                MHook.wHitTestCode = HitTest;
-                MHook.dwExtraInfo  = 0;
-                co_HOOK_CallHooks( WH_CBT,
-                                   HCBT_CLICKSKIPPED,
-                                   Msg->Msg.message,
-                                  (LPARAM)&MHook);
-            }
-            return FALSE;
-         }
-      }
+      if ( ISITHOOKED(WH_MOUSE) && IS_MOUSE_MESSAGE(Msg->Msg.message))
+      {
+          if(!ProcessMouseMessage(&Msg->Msg, HitTest, RemoveMsg))
+                 {
+                         return FALSE;
+                 }
+         }
 
-      if ( ISITHOOKED(WH_KEYBOARD) &&
-          (Msg->Msg.message == WM_KEYDOWN || Msg->Msg.message == WM_KEYUP) )
+      if ( ISITHOOKED(WH_KEYBOARD) && IS_KBD_MESSAGE(Msg->Msg.message))
       {
-         if (co_HOOK_CallHooks( WH_KEYBOARD,
-                                RemoveMsg ? HC_ACTION : HC_NOREMOVE,
-                                LOWORD(Msg->Msg.wParam),
-                                Msg->Msg.lParam))
-         {
-            if (ISITHOOKED(WH_CBT))
-            {
-               /* skip this message */
-               co_HOOK_CallHooks( WH_CBT,
-                                  HCBT_KEYSKIPPED,
-                                  LOWORD(Msg->Msg.wParam),
-                                  Msg->Msg.lParam );
-            }
-            return FALSE;
-         }
+          if(!ProcessKeyboardMessage(&Msg->Msg, RemoveMsg))
+          {
+              return FALSE;
+          }
       }
       // The WH_GETMESSAGE hook enables an application to monitor messages about to
       // be returned by the GetMessage or PeekMessage function.
index 4519ff8..be2b1a1 100644 (file)
@@ -9,7 +9,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 27faa8f..48ef50b 100644 (file)
@@ -8,7 +8,7 @@
  *       2003/05/22  Created
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 072bad9..541b3bf 100644 (file)
@@ -27,7 +27,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 /* FIXME: find include file for these */
 #define MONITORINFOF_PRIMARY      1
index 2b1feda..16323ae 100644 (file)
@@ -28,7 +28,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -174,8 +174,41 @@ MsqInsertSystemMessage(MSG* Msg)
    LARGE_INTEGER LargeTickCount;
    KIRQL OldIrql;
    ULONG Prev;
-   EVENTMSG Event;
+   MSLLHOOKSTRUCT MouseHookData;
 
+   KeQueryTickCount(&LargeTickCount);
+   Msg->time = MsqCalculateMessageTime(&LargeTickCount);
+
+   MouseHookData.pt.x = LOWORD(Msg->lParam);
+   MouseHookData.pt.y = HIWORD(Msg->lParam);
+   switch(Msg->message)
+   {
+        case WM_MOUSEWHEEL:
+           MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg->wParam));
+           break;
+        case WM_XBUTTONDOWN:
+        case WM_XBUTTONUP:
+        case WM_XBUTTONDBLCLK:
+        case WM_NCXBUTTONDOWN:
+        case WM_NCXBUTTONUP:
+        case WM_NCXBUTTONDBLCLK:
+           MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg->wParam));
+           break;
+        default:
+           MouseHookData.mouseData = 0;
+           break;
+     }
+     MouseHookData.flags = 0;
+     MouseHookData.time = Msg->time;
+     MouseHookData.dwExtraInfo = 0;
+     if( co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg->message, (LPARAM) &MouseHookData))
+         return;
+
+   /*
+    * If we got WM_MOUSEMOVE and there are already messages in the
+    * system message queue, check if the last message is mouse move
+    * and if it is then just overwrite it.
+    */
    IntLockSystemMessageQueue(OldIrql);
 
    /*
@@ -189,22 +222,6 @@ MsqInsertSystemMessage(MSG* Msg)
       return;
    }
 
-   KeQueryTickCount(&LargeTickCount);
-   Msg->time = MsqCalculateMessageTime(&LargeTickCount);
-
-   Event.message = Msg->message;
-   Event.time    = Msg->time;
-   Event.hwnd    = Msg->hwnd;
-   Event.paramL  = Msg->pt.x;
-   Event.paramH  = Msg->pt.y;
-   co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
-
-   /*
-    * If we got WM_MOUSEMOVE and there are already messages in the
-    * system message queue, check if the last message is mouse move
-    * and if it is then just overwrite it.
-    */
-
    if (Msg->message == WM_MOUSEMOVE && SystemMessageQueueCount)
    {
       if (SystemMessageQueueTail == 0)
@@ -623,7 +640,6 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Windo
    {
       PUSER_MESSAGE UserMsg;
       MSG Msg;
-      BOOL ProcessMessage;
 
       ASSERT(SystemMessageQueueHead < SYSTEM_MESSAGE_QUEUE_SIZE);
       Msg = SystemMessageQueue[SystemMessageQueueHead];
@@ -631,48 +647,14 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Windo
          (SystemMessageQueueHead + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
       SystemMessageQueueCount--;
       IntUnLockSystemMessageQueue(OldIrql);
-      if (WM_MOUSEFIRST <= Msg.message && Msg.message <= WM_MOUSELAST)
-      {
-         MSLLHOOKSTRUCT MouseHookData;
 
-         MouseHookData.pt.x = LOWORD(Msg.lParam);
-         MouseHookData.pt.y = HIWORD(Msg.lParam);
-         switch(Msg.message)
-         {
-            case WM_MOUSEWHEEL:
-               MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg.wParam));
-               break;
-            case WM_XBUTTONDOWN:
-            case WM_XBUTTONUP:
-            case WM_XBUTTONDBLCLK:
-            case WM_NCXBUTTONDOWN:
-            case WM_NCXBUTTONUP:
-            case WM_NCXBUTTONDBLCLK:
-               MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg.wParam));
-               break;
-            default:
-               MouseHookData.mouseData = 0;
-               break;
-         }
-         MouseHookData.flags = 0;
-         MouseHookData.time = Msg.time;
-         MouseHookData.dwExtraInfo = 0;
-         ProcessMessage = (0 == co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION,
-                           Msg.message, (LPARAM) &MouseHookData));
-      }
-      else
-      {
-         ProcessMessage = TRUE;
-      }
-      if (ProcessMessage)
-      {
-         UserMsg = ExAllocateFromPagedLookasideList(&MessageLookasideList);
-         /* What to do if out of memory? For now we just panic a bit in debug */
-         ASSERT(UserMsg);
-         UserMsg->FreeLParam = FALSE;
-         UserMsg->Msg = Msg;
-         InsertTailList(&HardwareMessageQueueHead, &UserMsg->ListEntry);
-      }
+      UserMsg = ExAllocateFromPagedLookasideList(&MessageLookasideList);
+      /* What to do if out of memory? For now we just panic a bit in debug */
+      ASSERT(UserMsg);
+      UserMsg->FreeLParam = FALSE;
+      UserMsg->Msg = Msg;
+      InsertTailList(&HardwareMessageQueueHead, &UserMsg->ListEntry);
+
       IntLockSystemMessageQueue(OldIrql);
    }
    HardwareMessageQueueStamp++;
@@ -767,7 +749,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    MSG Msg;
    LARGE_INTEGER LargeTickCount;
    KBDLLHOOKSTRUCT KbdHookData;
-   EVENTMSG Event;
    BOOLEAN Entered = FALSE;
 
    DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n",
@@ -795,14 +776,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    KeQueryTickCount(&LargeTickCount);
    Msg.time = MsqCalculateMessageTime(&LargeTickCount);
 
-   Event.message = Msg.message;
-   Event.hwnd    = Msg.hwnd;
-   Event.time    = Msg.time;
-   Event.paramL  = (Msg.wParam & 0xFF) | (HIWORD(Msg.lParam) << 8);
-   Event.paramH  = Msg.lParam & 0x7FFF;
-   if (HIWORD(Msg.lParam) & 0x0100) Event.paramH |= 0x8000;
-   co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
-
    /* We can't get the Msg.pt point here since we don't know thread
       (and thus the window station) the message will end up in yet. */
 
index f9104fe..2430a4d 100644 (file)
@@ -7,7 +7,7 @@
  * REVISION HISTORY:
  *       04-06-2001  CSH  Created
  */
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index e51db8e..569acfd 100644 (file)
@@ -9,7 +9,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index cd5f591..2ccc435 100644 (file)
@@ -22,7 +22,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 66977db..ce612a5 100644 (file)
@@ -11,7 +11,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index cf41600..c596c0e 100644 (file)
@@ -27,7 +27,7 @@
  */
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 065c7cc..8efd872 100644 (file)
@@ -10,7 +10,7 @@
  */
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 1a8cddc..88e4531 100644 (file)
@@ -24,7 +24,7 @@
  * PROGRAMER:        Gunnar
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index f0dcc3a..77d8fb9 100644 (file)
@@ -8,7 +8,7 @@
  *       2008/03/20  Split from misc.c
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 4768cb0..c39d06a 100644 (file)
@@ -11,7 +11,7 @@
 // - does setting invalid fonts work?
 // - save appropriate text metrics
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index c706805..6ad4dde 100644 (file)
@@ -11,7 +11,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -279,7 +279,7 @@ PostTimerMessages(PWINDOW_OBJECT Window)
 
   if (!pTmr) return FALSE;
 
-  if (Window && (int)Window != 1)
+  if (Window && ((ULONG_PTR)Window != 1))
   {
      if (!Window->Wnd) return FALSE;
   }
@@ -294,6 +294,7 @@ PostTimerMessages(PWINDOW_OBJECT Window)
           (pTmr->pti == pti) &&
           (pTmr->pWnd == Window))
         {
+           ASSERT((ULONG_PTR)Window != 1);
            Msg.hwnd    = Window->hSelf;
            Msg.message = (pTmr->flags & TMRF_SYSTEM) ? WM_SYSTIMER : WM_TIMER;
            Msg.wParam  = (WPARAM) pTmr->nID;
@@ -526,6 +527,8 @@ IntKillTimer(HWND Wnd, UINT_PTR IDEvent, BOOL SystemTimer)
       ASSERT(RtlAreBitsSet(&WindowLessTimersBitMap, IDEvent - 1, 1));
       RtlClearBits(&WindowLessTimersBitMap, IDEvent - 1, 1);
 
+      HintIndex = IDEvent - 1;
+
       IntUnlockWindowlessTimerBitmap();
    }
 
index 61b4164..ca72f61 100644 (file)
@@ -24,7 +24,7 @@
  * PROGRAMER:        Filip Navara <xnavara@volny.cz>
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index f82ed55..d82e384 100644 (file)
@@ -24,7 +24,7 @@
  * PROGRAMMER:       Ge van Geldorp (ge@gse.nl)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index bde42e1..ed49ac6 100644 (file)
@@ -9,7 +9,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -736,7 +736,7 @@ DceFreeWindowDCE(PWINDOW_OBJECT Window)
            else
            {
               DPRINT1("Not POWNED or CLASSDC hwndCurrent -> %x \n", pDCE->hwndCurrent);
-              ASSERT(FALSE);
+              //ASSERT(FALSE);
            }
         }
         else
index 4445fff..f22c6dc 100644 (file)
@@ -10,7 +10,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -2333,6 +2333,11 @@ AllocErr:
 
    IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window->Wnd, OBJID_WINDOW, 0);
 
+   /* By setting the flag below it can be examined to determine if the window
+      was created successfully and a valid pwnd was passed back to caller since
+      from here the function has to succeed. */
+   Window->Wnd->state2 |= WNDS2_WMCREATEMSGPROCESSED;
+
    /* Send move and size messages. */
    if (!(Window->state & WINDOWOBJECT_NEED_SIZE))
    {
@@ -2614,6 +2619,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
    BOOLEAN isChild;
    PWND Wnd;
    HWND hWnd;
+   PTHREADINFO ti;
 
    ASSERT_REFS_CO(Window); // FIXME: temp hack?
 
@@ -2633,8 +2639,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
       return FALSE;
    }
 
-   /* Call hooks */
-   if (ISITHOOKED(WH_CBT))
+   /* If window was created successfully and it is hooked */
+   if ((Wnd->state2 & WNDS2_WMCREATEMSGPROCESSED) && (ISITHOOKED(WH_CBT)))
    {
       if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0)) return FALSE;
    }
@@ -2657,6 +2663,21 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
    if (Window->pti->MessageQueue->CaptureWindow == Window->hSelf)
       Window->pti->MessageQueue->CaptureWindow = NULL;
 
+   /*
+    * Check if this window is the Shell's Desktop Window. If so set hShellWindow to NULL
+    */
+
+   ti = PsGetCurrentThreadWin32Thread();
+
+   if ((ti != NULL) & (ti->pDeskInfo != NULL))
+   {
+      if (ti->pDeskInfo->hShellWindow == hWnd)
+      {
+         DPRINT1("Destroying the ShellWindow!\n");
+         ti->pDeskInfo->hShellWindow = NULL;
+      }
+   }
+
    IntDereferenceMessageQueue(Window->pti->MessageQueue);
 
    IntEngWindowChanged(Window, WOC_DELETE);
@@ -4263,8 +4284,8 @@ NtUserRegisterWindowMessage(PUNICODE_STRING MessageNameUnsafe)
    }
 
    Ret = (UINT)IntAddAtom(SafeMessageName.Buffer);
-
-   ExFreePoolWithTag(SafeMessageName.Buffer, TAG_STRING);
+   if (SafeMessageName.Buffer)
+      ExFreePoolWithTag(SafeMessageName.Buffer, TAG_STRING);
    RETURN( Ret);
 
 CLEANUP:
index 13c5861..ab45d97 100644 (file)
@@ -27,7 +27,7 @@
  */
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index a379a2f..2d26c8d 100644 (file)
@@ -33,7 +33,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index e1bbc89..5839303 100644 (file)
@@ -1,4 +1,4 @@
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 0071015..3e20c29 100644 (file)
@@ -18,7 +18,7 @@
  */
 /* $Id$ */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index a02d652..6261ab4 100644 (file)
@@ -18,7 +18,7 @@
 */
 /* $Id: bitmaps.c 28300 2007-08-12 15:20:09Z tkreuzer $ */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 658b53d..f471a67 100644 (file)
@@ -17,7 +17,7 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 6e827fa..c8682f6 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:         
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -709,6 +709,7 @@ NtGdiSetBrushOrg(HDC hDC, INT XOrg, INT YOrg, LPPOINT Point)
 
     pdcattr->ptlBrushOrigin.x = XOrg;
     pdcattr->ptlBrushOrigin.y = YOrg;
+    IntptlBrushOrigin(dc, XOrg, YOrg );
     DC_UnlockDc(dc);
 
     return TRUE;
index acfc99b..c5297c3 100644 (file)
@@ -17,7 +17,7 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 6b80f1d..7310dcb 100644 (file)
@@ -27,7 +27,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -1133,6 +1133,16 @@ IntCalcFillOrigin(PDC pdc)
     return pdc->ptlFillOrigin.y;
 }
 
+PPOINTL
+FASTCALL
+IntptlBrushOrigin(PDC pdc, LONG x, LONG y )
+{
+    pdc->dclevel.ptlBrushOrigin.x = x;
+    pdc->dclevel.ptlBrushOrigin.y = y;
+    IntCalcFillOrigin(pdc);
+    return &pdc->dclevel.ptlBrushOrigin;
+}
+
 VOID
 APIENTRY
 GdiSetDCOrg(HDC hDC, LONG Left, LONG Top, PRECTL prc)
index 562d754..9b445b1 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:         Timo Kreuzer (timo.kreuzer@rectos.org)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 3837b78..3791a6a 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:         Timo Kreuzer (timo.kreuzer@rectos.org)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 #include <bugcodes.h>
 
 #define NDEBUG
@@ -119,6 +119,8 @@ DC_AllocDC(PUNICODE_STRING Driver)
 
     pdcattr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT);
     TextIntRealizeFont(pdcattr->hlfntNew,NULL);
+    NewDC->hlfntCur = pdcattr->hlfntNew;
+    NewDC->dclevel.plfnt = GDIOBJ_GetKernelObj(pdcattr->hlfntNew);
 
     NewDC->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE);
     NewDC->dclevel.ppal = PALETTE_ShareLockPalette(NewDC->dclevel.hpal);
@@ -586,8 +588,59 @@ DC_InitDC(HDC  DCHandle)
     NtGdiSetVirtualResolution(DCHandle, 0, 0, 0, 0);
 }
 
+BOOL
+FASTCALL
+MakeInfoDC(PDC pdc, BOOL bSet)
+{
+    PSURFACE pSurface;
+    SIZEL sizl;
+
+    /* Can not be a display DC. */
+    if (pdc->fs & DC_FLAG_DISPLAY) return FALSE;
+    if (bSet)
+    {
+        if (pdc->fs & DC_FLAG_TEMPINFODC || pdc->dctype == DC_TYPE_DIRECT)
+            return FALSE;
+
+        pSurface = pdc->dclevel.pSurface;
+        pdc->fs |= DC_FLAG_TEMPINFODC;
+        pdc->pSurfInfo = pSurface;
+        pdc->dctype = DC_TYPE_INFO;
+        pdc->dclevel.pSurface = NULL;
+
+        PDEV_sizl(pdc->ppdev, &sizl);
+
+        if ( sizl.cx == pdc->dclevel.sizl.cx &&
+             sizl.cy == pdc->dclevel.sizl.cy )
+            return TRUE;
+
+        pdc->dclevel.sizl.cx = sizl.cx;
+        pdc->dclevel.sizl.cy = sizl.cy;
+    }
+    else
+    {
+        if (!(pdc->fs & DC_FLAG_TEMPINFODC) || pdc->dctype != DC_TYPE_INFO)
+            return FALSE;
+
+        pSurface = pdc->pSurfInfo;
+        pdc->fs &= ~DC_FLAG_TEMPINFODC;
+        pdc->dclevel.pSurface = pSurface;
+        pdc->dctype = DC_TYPE_DIRECT;
+        pdc->pSurfInfo = NULL;
+
+        if ( !pSurface ||
+             (pSurface->SurfObj.sizlBitmap.cx == pdc->dclevel.sizl.cx &&
+              pSurface->SurfObj.sizlBitmap.cy == pdc->dclevel.sizl.cy) )
+            return TRUE;
+
+        pdc->dclevel.sizl.cx = pSurface->SurfObj.sizlBitmap.cx;
+        pdc->dclevel.sizl.cy = pSurface->SurfObj.sizlBitmap.cy;
+    }
+    return IntSetDefaultRegion(pdc);
+}
+
 /*
-* @unimplemented
+* @implemented
 */
 BOOL
 APIENTRY
@@ -595,7 +648,14 @@ NtGdiMakeInfoDC(
     IN HDC hdc,
     IN BOOL bSet)
 {
-    UNIMPLEMENTED;
+    BOOL Ret;
+    PDC pdc = DC_LockDc(hdc);
+    if (pdc)
+    {
+        Ret = MakeInfoDC(pdc, bSet);
+        DC_UnlockDc(pdc);
+        return Ret;
+    }
     return FALSE;
 }
 
@@ -704,34 +764,16 @@ NtGdiCreateCompatibleDC(HDC hDC)
 BOOL
 APIENTRY
 NtGdiDeleteObjectApp(HANDLE DCHandle)
-{
-    /* Complete all pending operations */
-    NtGdiFlushUserBatch();
-
-    if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
-
-    if (GDI_HANDLE_GET_TYPE(DCHandle) != GDI_OBJECT_TYPE_DC)
-        return GreDeleteObject((HGDIOBJ) DCHandle);
-
-    if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
-
-    if (!GDIOBJ_OwnedByCurrentProcess(DCHandle))
-    {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-
-    return IntGdiDeleteDC(DCHandle, FALSE);
-}
-
-BOOL
-APIENTRY
-NewNtGdiDeleteObjectApp(HANDLE DCHandle)
 {
   GDIOBJTYPE ObjType;
 
+  /* Complete all pending operations */
+  NtGdiFlushUserBatch();
+
   if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
 
+  if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
+
   ObjType = GDI_HANDLE_GET_TYPE(DCHandle) >> GDI_ENTRY_UPPER_SHIFT;
 
   if (GreGetObjectOwner( DCHandle, ObjType))
index e35fa71..0bafaad 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:         Timo Kreuzer (timo.kreuzer@rectos.org)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -110,6 +110,9 @@ DC_vUpdateTextBrush(PDC pdc)
 {
     PDC_ATTR pdcattr = pdc->pdcattr;
 
+    if(pdcattr->ulDirty_ & DIRTY_TEXT)
+        EBRUSHOBJ_vUpdate(&pdc->eboText, pdc->eboText.pbrush, pdc);
+
     /* Update the eboText's solid color */
     EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, pdcattr->crForegroundClr);
 
@@ -123,6 +126,9 @@ DC_vUpdateBackgroundBrush(PDC pdc)
 {
     PDC_ATTR pdcattr = pdc->pdcattr;
 
+    if(pdcattr->ulDirty_ & DIRTY_BACKGROUND)
+        EBRUSHOBJ_vUpdate(&pdc->eboBackground, pdc->eboBackground.pbrush, pdc);
+
     /* Update the eboBackground's solid color */
     EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, pdcattr->crBackgroundClr);
 
index 9e491a4..1b97ae7 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:         Timo Kreuzer (timo.kreuzer@rectos.org)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 9721af3..f856ea1 100644 (file)
@@ -1,5 +1,5 @@
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -125,6 +125,71 @@ IntIsPrimarySurface(SURFOBJ *SurfObj)
 }
 #endif
 
+BOOL
+FASTCALL
+IntSetDefaultRegion(PDC pdc)
+{
+    PSURFACE pSurface;
+    PROSRGNDATA prgn;
+    RECTL rclWnd, rclClip;
+
+    IntGdiReleaseRaoRgn(pdc);
+
+    rclWnd.left   = 0;
+    rclWnd.top    = 0;
+    rclWnd.right  = pdc->dclevel.sizl.cx;
+    rclWnd.bottom = pdc->dclevel.sizl.cy;
+    rclClip = rclWnd;
+
+//    EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
+    if (pdc->ppdev->flFlags & PDEV_META_DEVICE)
+    {
+        pSurface = pdc->dclevel.pSurface;
+        if (pSurface && pSurface->flFlags & PDEV_SURFACE)
+        {
+            rclClip.left   += pdc->ppdev->ptlOrigion.x;
+            rclClip.top    += pdc->ppdev->ptlOrigion.y;
+            rclClip.right  += pdc->ppdev->ptlOrigion.x;
+            rclClip.bottom += pdc->ppdev->ptlOrigion.y;
+        }
+    }
+//    EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
+
+    prgn = pdc->prgnVis;
+
+    if (prgn && prgn != prgnDefault)
+    {
+        REGION_SetRectRgn( prgn,
+                           rclClip.left,
+                           rclClip.top,
+                           rclClip.right ,
+                           rclClip.bottom );
+    }
+    else
+    {
+        prgn = IntSysCreateRectpRgn( rclClip.left,
+                                     rclClip.top,
+                                     rclClip.right ,
+                                     rclClip.bottom );
+        pdc->prgnVis = prgn;
+    }
+
+    if (prgn)
+    {
+        pdc->ptlDCOrig.x = 0;
+        pdc->ptlDCOrig.y = 0;
+        pdc->erclWindow = rclWnd;
+        pdc->erclClip = rclClip;
+        /* Might be an InitDC or DCE....*/
+        pdc->ptlFillOrigin.x = pdc->dcattr.VisRectRegion.Rect.right;
+        pdc->ptlFillOrigin.y = pdc->dcattr.VisRectRegion.Rect.bottom;
+        return TRUE;
+    }
+
+    pdc->prgnVis = prgnDefault;
+    return FALSE;
+}
+
 
 BOOL APIENTRY
 NtGdiCancelDC(HDC  hDC)
index 40a7956..b8d322f 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:         Timo Kreuzer (timo.kreuzer@rectos.org)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -19,6 +19,22 @@ static KEVENT VideoDriverNeedsPreparation;
 static KEVENT VideoDriverPrepared;
 PDC defaultDCstate = NULL;
 
+PSIZEL
+FASTCALL
+PDEV_sizl(PPDEVOBJ ppdev, PSIZEL psizl)
+{
+    if (ppdev->flFlags & PDEV_META_DEVICE)
+    {
+        psizl->cx = ppdev->ulHorzRes;
+        psizl->cy = ppdev->ulVertRes;
+    }
+    else
+    {
+        psizl->cx = ppdev->gdiinfo.ulHorzRes;
+        psizl->cy = ppdev->gdiinfo.ulVertRes;
+    }
+    return psizl;
+}
 
 NTSTATUS FASTCALL
 InitDcImpl(VOID)
index cc2a16e..2ec35e6 100644 (file)
@@ -17,7 +17,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 073ee1a..0cc9a23 100755 (executable)
@@ -49,7 +49,7 @@ SUCH DAMAGE.
     Modified for ReactOS
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 7da0540..aa133f8 100644 (file)
@@ -17,7 +17,7 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 41a75cd..a0837e1 100644 (file)
@@ -8,7 +8,7 @@
       
 /** Includes ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -251,6 +251,49 @@ RealizeFontInit(HFONT hFont)
   return pTextObj;
 }
 
+HFONT
+FASTCALL
+GreSelectFont( HDC hDC, HFONT hFont)
+{
+    PDC pdc;
+    PDC_ATTR pdcattr;
+    PTEXTOBJ pOrgFnt, pNewFnt = NULL;
+    HFONT hOrgFont = NULL;
+
+    if (!hDC || !hFont) return NULL;
+
+    pdc = DC_LockDc(hDC);
+    if (!pdc)
+    {
+        return NULL;
+    }
+
+    if (NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL)))
+    {
+       /* LFONTOBJ use share and locking. */
+       pNewFnt = TEXTOBJ_LockText(hFont);
+       pdcattr = pdc->pdcattr;
+       pOrgFnt = pdc->dclevel.plfnt;
+       if (pOrgFnt)
+       {
+          hOrgFont = pOrgFnt->BaseObject.hHmgr;
+       }
+       else
+       {
+          hOrgFont = pdcattr->hlfntNew;
+       }
+       pdc->dclevel.plfnt = pNewFnt;
+       pdc->hlfntCur = hFont;
+       pdcattr->hlfntNew = hFont;
+       pdcattr->ulDirty_ |= DIRTY_CHARSET;
+       pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
+    }
+
+    if (pNewFnt) TEXTOBJ_UnlockText(pNewFnt);
+    DC_UnlockDc(pdc);
+    return hOrgFont;
+}
+
 /** Functions ******************************************************************/
 
 INT
@@ -933,30 +976,7 @@ NtGdiSelectFont(
     IN HDC hDC,
     IN HFONT hFont)
 {
-    PDC pDC;
-    PDC_ATTR pdcattr;
-    HFONT hOrgFont = NULL;
-
-    if (hDC == NULL || hFont == NULL) return NULL;
-
-    pDC = DC_LockDc(hDC);
-    if (!pDC)
-    {
-        return NULL;
-    }
-
-    pdcattr = pDC->pdcattr;
-
-    /* FIXME: what if not successful? */
-    if(NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL)))
-    {
-        hOrgFont = pdcattr->hlfntNew;
-        pdcattr->hlfntNew = hFont;
-    }
-
-    DC_UnlockDc(pDC);
-
-    return hOrgFont;
+    return GreSelectFont(hDC, hFont);
 }
 
 
index fea0c10..478863d 100644 (file)
@@ -35,7 +35,7 @@
 
 /** Includes ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
index b958ad4..11d3628 100644 (file)
@@ -1,5 +1,5 @@
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -106,9 +106,10 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
      case GdiBCSetBrushOrg:
      {
         PGDIBSSETBRHORG pgSBO;
-        if(!dc) break;
+        if (!dc) break;
         pgSBO = (PGDIBSSETBRHORG) pHdr;
         pdcattr->ptlBrushOrigin = pgSBO->ptlBrushOrigin;
+        IntptlBrushOrigin(dc, pgSBO->ptlBrushOrigin.x, pgSBO->ptlBrushOrigin.y);
         break;
      }
      case GdiBCExtSelClipRgn:
@@ -116,10 +117,34 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
      case GdiBCSelObj:
      {
         PGDIBSOBJECT pgO;
-        if(!dc) break;
+        PTEXTOBJ pOrgFnt, pNewFnt = NULL;
+        HFONT hOrgFont = NULL;
+
+        if (!dc) break;
         pgO = (PGDIBSOBJECT) pHdr;
-        TextIntRealizeFont((HFONT) pgO->hgdiobj, NULL);
-        pdcattr->ulDirty_ &= ~(DIRTY_CHARSET);
+
+        if (NT_SUCCESS(TextIntRealizeFont((HFONT)pgO->hgdiobj,NULL)))
+        {
+           /* LFONTOBJ use share and locking. */
+           pNewFnt = TEXTOBJ_LockText(pgO->hgdiobj);
+
+           pOrgFnt = dc->dclevel.plfnt;
+           if (pOrgFnt)
+           {
+              hOrgFont = pOrgFnt->BaseObject.hHmgr;
+           }
+           else
+           {
+              hOrgFont = pdcattr->hlfntNew;
+           }
+           dc->dclevel.plfnt = pNewFnt;
+           dc->hlfntCur = pgO->hgdiobj;
+           pdcattr->hlfntNew = pgO->hgdiobj;
+           pdcattr->ulDirty_ |= DIRTY_CHARSET;
+           pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
+        }
+        if (pNewFnt) TEXTOBJ_UnlockText(pNewFnt);
+        break;
      }
      case GdiBCDelRgn:
         DPRINT("Delete Region Object!\n");
index a9991ad..efa686f 100644 (file)
@@ -3,23 +3,48 @@
 #define KeRosDumpStackFrames(Frames, Count) KdSystemDebugControl('DsoR', (PVOID)Frames, Count, NULL, 0, NULL, KernelMode)
 NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags);
 
-static int leak_reported = 0;
-#define GDI_STACK_LEVELS 12
-static ULONG GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
-static ULONG GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
-static ULONG GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
-static ULONG GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
+#define GDI_STACK_LEVELS 20
+static ULONG_PTR GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
+static ULONG_PTR GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
+static ULONG_PTR GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
+static ULONG_PTR GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
 struct DbgOpenGDIHandle
 {
     ULONG idx;
     int count;
 };
-#define H 1024
-static struct DbgOpenGDIHandle h[H];
+#define MAX_BACKTRACES 1024
+static struct DbgOpenGDIHandle AllocatorTable[MAX_BACKTRACES];
+
+static
+BOOL
+CompareBacktraces(ULONG idx1, ULONG idx2)
+{
+    ULONG iLevel;
+
+    /* Loop all stack levels */
+    for (iLevel = 0; iLevel < GDI_STACK_LEVELS; iLevel++)
+    {
+        if (GDIHandleAllocator[idx1][iLevel]
+                != GDIHandleAllocator[idx2][iLevel])
+//        if (GDIHandleShareLocker[idx1][iLevel]
+//                != GDIHandleShareLocker[idx2][iLevel])
+        {
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+#define IS_HANDLE_VALID(idx) \
+    ((GdiHandleTable->Entries[idx].Type & GDI_ENTRY_BASETYPE_MASK) != 0)
 
 void IntDumpHandleTable(PGDI_HANDLE_TABLE HandleTable)
 {
-    int i, n = 0, j, k, J;
+    static int leak_reported = 0;
+    int i, j, idx, nTraces = 0;
+    KIRQL OldIrql;
 
     if (leak_reported)
     {
@@ -30,68 +55,79 @@ void IntDumpHandleTable(PGDI_HANDLE_TABLE HandleTable)
     leak_reported = 1;
     DPRINT1("reporting gdi handle abusers:\n");
 
-    /* step through GDI handle table and find out who our culprit is... */
-    for (i = RESERVE_ENTRIES_COUNT; i < GDI_HANDLE_COUNT; i++)
+    /* We've got serious business to do */
+    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+
+    /* Step through GDI handle table and find out who our culprit is... */
+    for (idx = RESERVE_ENTRIES_COUNT; idx < GDI_HANDLE_COUNT; idx++)
     {
-        for (j = 0; j < n; j++)
+        /* If the handle is free, continue */
+        if (!IS_HANDLE_VALID(idx)) continue;
+
+        /* Step through all previous backtraces */
+        for (j = 0; j < nTraces; j++)
         {
-next:
-            J = h[j].idx;
-            for (k = 0; k < GDI_STACK_LEVELS; k++)
+            /* Check if the backtrace matches */
+            if (CompareBacktraces(idx, AllocatorTable[j].idx))
             {
-                if (GDIHandleAllocator[i][k]
-                        != GDIHandleAllocator[J][k])
-                {
-                    if (++j == n)
-                        goto done;
-                    else
-                        goto next;
-                }
+                /* It matches, increment count and break out */
+                AllocatorTable[j].count++;
+                break;
             }
-            goto done;
         }
-done:
-        if (j < H)
+
+        /* Did we find a new backtrace? */
+        if (j == nTraces)
         {
-            if (j == n)
-            {
-                h[j].idx = i;
-                h[j].count = 1;
-                n = n + 1;
-            }
-            else
-                h[j].count++;
+            /* Break out, if we reached the maximum */
+            if (nTraces == MAX_BACKTRACES) break;
+
+            /* Initialize this entry */
+            AllocatorTable[j].idx = idx;
+            AllocatorTable[j].count = 1;
+            nTraces++;
         }
     }
+
     /* bubble sort time! weeeeee!! */
-    for (i = 0; i < n-1; i++)
+    for (i = 0; i < nTraces-1; i++)
     {
-        if (h[i].count < h[i+1].count)
+        if (AllocatorTable[i].count < AllocatorTable[i+1].count)
         {
-            struct DbgOpenGDIHandle t;
-            t = h[i+1];
-            h[i+1] = h[i];
+            struct DbgOpenGDIHandle temp;
+
+            temp = AllocatorTable[i+1];
+            AllocatorTable[i+1] = AllocatorTable[i];
             j = i;
-            while (j > 0 && h[j-1].count < t.count)
+            while (j > 0 && AllocatorTable[j-1].count < temp.count)
                 j--;
-            h[j] = t;
+            AllocatorTable[j] = temp;
         }
     }
-    /* print the worst offenders... */
-    DbgPrint("Worst GDI Handle leak offenders (out of %i unique locations):\n", n);
-    for (i = 0; i < n && h[i].count > 1; i++)
+
+    /* Print the worst offenders... */
+    DbgPrint("Worst GDI Handle leak offenders (out of %i unique locations):\n", nTraces);
+    for (i = 0; i < nTraces && AllocatorTable[i].count > 1; i++)
     {
         /* Print out the allocation count */
-        DbgPrint(" %i allocs: ", h[i].count);
+        DbgPrint(" %i allocs, type = 0x%lx:\n", 
+                 AllocatorTable[i].count, 
+                 GdiHandleTable->Entries[AllocatorTable[i].idx].Type);
 
         /* Dump the frames */
-        KeRosDumpStackFrames(GDIHandleAllocator[h[i].idx], GDI_STACK_LEVELS);
+        KeRosDumpStackFrames(GDIHandleAllocator[AllocatorTable[i].idx], GDI_STACK_LEVELS);
+        //KeRosDumpStackFrames(GDIHandleShareLocker[AllocatorTable[i].idx], GDI_STACK_LEVELS);
 
         /* Print new line for better readability */
         DbgPrint("\n");
     }
-    if (i < n && h[i].count == 1)
+
+    if (i < nTraces)
         DbgPrint("(list terminated - the remaining entries have 1 allocation only)\n");
+
+    KeLowerIrql(OldIrql);
+
+    ASSERT(FALSE);
 }
 
 ULONG
@@ -101,11 +137,13 @@ CaptureStackBackTace(PVOID* pFrames, ULONG nFramesToCapture)
 
     memset(pFrames, 0x00, (nFramesToCapture + 1) * sizeof(PVOID));
 
-    nFrameCount = RtlCaptureStackBackTrace(1, nFramesToCapture, pFrames, NULL);
+    nFrameCount = RtlWalkFrameChain(pFrames, nFramesToCapture, 0);
 
     if (nFrameCount < nFramesToCapture)
     {
-        nFrameCount += RtlWalkFrameChain(pFrames + nFrameCount, nFramesToCapture - nFrameCount, 1);
+        nFrameCount += RtlWalkFrameChain(pFrames + nFrameCount,
+                                         nFramesToCapture - nFrameCount,
+                                         1);
     }
 
     return nFrameCount;
index 5af1413..0f73d9b 100644 (file)
@@ -10,7 +10,7 @@
 
 //#define GDI_DEBUG
 
-#include <w32k.h>
+#include <win32k.h>
 #define NDEBUG
 #include <debug.h>
 
index 7a32146..dd99ea3 100644 (file)
@@ -17,7 +17,7 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index bbf60f4..173b3f9 100644 (file)
@@ -17,7 +17,7 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 573dde4..dbc6284 100644 (file)
@@ -8,7 +8,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 61a50ec..8fcbbe4 100644 (file)
@@ -7,7 +7,7 @@
  *                    Timo Kreuzer
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 1dfca39..7d6c796 100644 (file)
@@ -32,7 +32,7 @@
  * PROGRAMMER:
  */
 
-#include <w32k.h>
+#include <win32k.h>
 #include "math.h"
 
 #define NDEBUG
index 6f60465..8d02e9b 100644 (file)
@@ -20,7 +20,7 @@
  * $Id$
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index f5fdc53..1f6196a 100644 (file)
@@ -27,7 +27,7 @@
  *                 21/2/2003: Created
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index bc56a2f..bf21047 100644 (file)
@@ -18,7 +18,7 @@
  */
 /* $Id$ */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index d98e79c..ea58e63 100644 (file)
@@ -18,7 +18,7 @@
  */
 /* $Id$ */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 3922016..165f86a 100644 (file)
@@ -113,7 +113,7 @@ SOFTWARE.
  * the y-x-banding that's so nice to have...
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 40708b6..5499a6f 100644 (file)
@@ -22,7 +22,7 @@
  *
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 14376a1..07cf12d 100644 (file)
@@ -8,7 +8,7 @@
       
 /** Includes ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 150a762..72add55 100644 (file)
@@ -18,7 +18,7 @@
  */
 /* $Id$ */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
index 74453d5..9ba7311 100644 (file)
@@ -8,7 +8,7 @@
 
 /** Includes ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 #define NDEBUG
 #include <debug.h>
 
index 4bbbeb9..90075c8 100644 (file)
@@ -60,7 +60,7 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
 #include <ntgdi.h>
 
 /* Internal Win32K Header */
-#include "include/win32k.h"
+#include "include/win32kp.h"
 
 /* Undocumented stuff */
 typedef DRIVEROBJ *PDRIVEROBJ;
index a1e610b..82a8555 100644 (file)
@@ -2,7 +2,7 @@
  * Stubs for unimplemented WIN32K.SYS exports
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define UNIMPLEMENTED DbgPrint("(%s:%i) WIN32K: %s UNIMPLEMENTED\n", __FILE__, __LINE__, __FUNCTION__ )
 
index 3ceadbb..9ecafb9 100644 (file)
@@ -1,4 +1,4 @@
-#include <w32k.h>
+#include <win32k.h>
 
 #define UNIMPLEMENTED DbgPrint("(%s:%i) WIN32K: %s UNIMPLEMENTED\n", __FILE__, __LINE__, __FUNCTION__ )